问题是我要在action类的某个方法上执行拦截器,官网给出的例子如下:package com.example.actions;import com.opensymphony.xwork2.ActionSupport; 
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Actions;@InterceptorRefs({
    @InterceptorRef("interceptor-1"),
    @InterceptorRef("defaultStack")
})
public class HelloWorld extends ActionSupport {
  @Action(value="action1", interceptorRefs=@InterceptorRef("validation"))
  public String execute() {
    return SUCCESS;
  }  @Action(value="action2")
  public String doSomething() {
    return SUCCESS;
  }
}下面的拦截机将会应用到“action1”中:"interceptor-1","defaultStack"中的所有拦截机, "validation"
"defaultStack"中的所有拦截机也会对”action2”生效我自己写了个拦截器栈parmsUrl,配置文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN"
        "http://struts.apache.org/dtds/struts-2.1.dtd">
<struts>
<constant name="struts.convention.default.parent.package" value="crud-default" />
<constant name="struts.convention.package.locators" value="web" />
<constant name="struts.convention.package.locators.basePackage" value="org.springside.examples.miniweb" /> <!-- 用于CRUD Action的parent package -->
<package name="crud-default" extends="convention-default">
<!-- 基于paramsPrepareParamsStack,
增加store interceptor保证actionMessage在redirect后不会丢失 -->
<interceptors>
    <interceptor name="urlparm" class="org.springside.examples.miniweb.interceptor.UrlParmInterceptor"></interceptor>
<interceptor-stack name="crudStack">
<interceptor-ref name="store">
<param name="operationMode">AUTOMATIC</param>
</interceptor-ref>
<interceptor-ref name="paramsPrepareParamsStack" />
</interceptor-stack>
<interceptor-stack name="parmsUrl">
    <interceptor-ref name="urlparm"/>
    <interceptor-ref name="crudStack"/>
   
</interceptor-stack>
</interceptors> <default-interceptor-ref name="crudStack" />
</package> <!-- 
使用Convention插件,实现约定大于配置的零配置文件风格.
           特殊的Result路径在Action类中使用@Result设定. 
-->

</struts>Action类如下/**
 * 用户管理Action.
 * 
 * 使用Struts2 convention-plugin annotation定义Action参数.
 * 演示带分页的管理界面.
 * 
 * @author calvin
 */
//定义URL映射对应/security/user.action
@Namespace("/security")
//定义名为reload的result重定向到user.action, 其他result则按照convention默认.
@Results( { @Result(name = CrudsActionSupports.RELOAD, location = "user.action", type = "redirect") })
public class UserAction extends CrudsActionSupports<User> {

private static final long serialVersionUID = 1L; @Autowired
private SecurityEntityManager securityEntityManager; //-- 页面属性 --//
private Long id;
private User entity;
private Page<User> page = new Page<User>(5,5);//每页5条记录
private List<Long> checkedRoleIds; //页面中钩选的角色id列表 //-- ModelDriven 与 Preparable函数 --//
public void setId(Long id) {
this.id = id;
} public User getModel() {
return entity;
} @Override
protected void prepareModel() throws Exception {
if (id != null) {
entity = securityEntityManager.getUser(id);
} else {
entity = new User();
}
} //-- CRUD Action 函数 --//
@SuppressWarnings("unchecked")
@Override
@Action(value="user",interceptorRefs=@InterceptorRef("parmsUrl"))
public String list() throws Exception {
List<PropertyFilter> filters = HibernateWebUtils.buildPropertyFilters(Struts2Utils.getRequest());
//设置默认排序方式

if (!page.isOrderBySetted()) {
page.setOrderBy("id");
page.setOrder(Page.ASC);
}
// String url=getParmUrl();
      page.setUrl((String)ServletActionContext.getRequest().getAttribute("page.url"));
// System.out.println("Action中获得参数:"+page.getUrl());
page.setFilename("user.action");
page = (Page)securityEntityManager.searchUser(page, filters);
return SUCCESS;
}

@Override
public String input() throws Exception {
checkedRoleIds = entity.getRoleIds();
return INPUT;
}@Action(value="user",interceptorRefs=@InterceptorRef("parmsUrl"))
这个就是我配置的拦截器,好了当我使用地址:http://localhost:8080/demo/security/user.action
parmsUrl起作用了,但我用地址
http://localhost:8080/demo/security/user!input.action?id=17parmsUrl也起作用了,这是为什么?我没在Input方法上放拦截器!当我调用user!save.action时还是起作用了,这明显是这个userAction类都生效了。。而我要的仅仅是在user.action时拦截。之后我又做了尝试:
在input方法上配置@Action(value="user!input",interceptorRefs=@InterceptorRef("parmsUrl"))
发现拦截器不起作用了,连使用http://localhost:8080/demo/security/user!input.action?id=17地址也不行。。

解决方案 »

  1.   

    拦截器默认是拦截action中的所有方法,注解方式不太了解,配置文件方式需要加include属性来声明要拦截的方法或者是不要拦截的方法,annotation应该差不多是相同的。
    楼主仅仅希望是在user.action的时候拦截,实际上也就是在访问execute方法的时候拦截
      

  2.   

    用注解没什么问题,但是拦截器是拦截action的,你用的user!save.action其实,拦截的还是user.action这个相当与配置文件中的action="user" method="save"struts2的拦截器是相对于action的,它既不是相对于类的也不是相对于方法的,这个原则一定要记住你可以直接用 user.action,saveUser.action,然后在你的方法上加上注解
    @Action("saveUser")
    public String save(){
      

  3.   

    事实上是在访问execute时拦截,因为在execute中是执行list函数的,但问题是拦截器还拦截了其他方法如input,save等等
      

  4.   


    谢谢大侠!但是如果“拦截器是拦截action的”,那么按您的意思是不能指定action下的具体method了?
      

  5.   

    我改成
    @Action(value="saveUser",interceptorRefs=@InterceptorRef("parmsUrl")) 
    public String save(){
    }
    使用地址
    http://localhost:8080/demo/security/saveUser!save.action?id=6
    确实能够拦截!但是报异常Could not find action or result,
    如果用
    http://localhost:8080/demo/security/user!save.action?id=6
    却不能拦截,但不报错
      

  6.   

    应该是这样吧
    http://localhost:8080/demo/security/saveUser.action?id=6 同时要定义返回,可以再action类上同意定义result,比如:
    @Results({
      @Result(name="input", location="/jsp/login/login.jsp"),
      ......
    })
    public class XxxAction如果楼主对struts2的注解不清楚的话,可以仔细看一下struts2.1.x自带的doc中的Convention Plugin
      

  7.   

    呵呵,现在搞明白了.如果单纯的执行那个saveUser.action,result默认返回的是/security/saveuser.jsp,所以报找不到action or result,谢谢Landor2004!分给你了!