Struts2 自定义拦截器栈后无法得到表单参数之解决办法

简介: 我自定义了一个拦截器,目的是在action执行之前像ValueStack中设置一些属性,代码是这样的:view plaincopy to clipboardprint?HttpServletRequest request=(HttpServletRequest)ActionContext.
我自定义了一个拦截器,目的是在action执行之前像ValueStack中设置一些属性,代码是这样的:

  1. HttpServletRequest request=(HttpServletRequest)ActionContext.getContext().get(StrutsStatics.HTTP_REQUEST); 
  2.       OgnlValueStack stack=(OgnlValueStack)request.getAttribute("struts.valueStack"); 
  3.   
  4.       /**
  5.        * Set the properties
  6.        */ 
  7.       List<Category> cityList=systemService.getCategorySortList("city"); 
  8.       stack.set("cityList",cityList); 
  9.        
  10.       EhcacheVindicatorProxy proxy=new EhcacheVindicatorProxy("menu"); 
  11.       List<FrontMenu> frontMenuList=(List)proxy.get(FrontMenu.class, "frontmenus", "menus.xml"); 
  12.       stack.set("frontMenuList",frontMenuList); 
  13.        
  14.       return invocation.invoke(); 
HttpServletRequest request=(HttpServletRequest)ActionContext.getContext().get(StrutsStatics.HTTP_REQUEST);        OgnlValueStack stack=(OgnlValueStack)request.getAttribute("struts.valueStack");         /**         * Set the properties         */        List<Category> cityList=systemService.getCategorySortList("city");        stack.set("cityList",cityList);                EhcacheVindicatorProxy proxy=new EhcacheVindicatorProxy("menu");        List<FrontMenu> frontMenuList=(List)proxy.get(FrontMenu.class, "frontmenus", "menus.xml");        stack.set("frontMenuList",frontMenuList);                return invocation.invoke();

struts.xml中是这样配置的:

<!--引用默认拦截器-->
                <interceptor-ref name="properties" />
                <interceptor-ref name="defaultStack" />

这样配置以后确实可以达到我要的效果,但是问题却出来了,这样配置以后表单参数无法获得,全都是默认为空。我们来看下面一段描述:

  

众所周知, Struts2 Action 类通过属性可以获得所有相关的值,如请求参数、 Action 配置参数、向其他 Action 传送属性值 ( 通过 chain 结果 ) 等等。要获得这些参数值,我们要做的唯一一件事就是在 Action 类中声明与参数同名的属性,在 Struts2 调用 Action 类的 Action 方法 ( 默认是 execute) 方法之前,就会为相应的 Action 属性赋值。

   要完成这个功能,有很大程度上, Struts 2 要依赖与 ValueStack 对象。这个对象贯穿整个 Action 的生命周期 ( 每个 Action 类的对象实例会拥有一个 ValueStack 对象 ) 。当 Struts 2 接收到一个 action 的请求后,会先建立 Action 类的对象实例,但不会调用 Action 方法,而是先将 Action 类的相应属性放到 ValueStack 对象的顶层节点 (ValueStack 对象相当于一个栈 ). 只是所有的属性值都是默认的值,如 String 类型的属性值为 null,int 类型的属性值为 0 等。

   在处理完上述工作后, Struts 2 就会调用拦截器链中的拦截器,当调用完所有的拦截器后,最后会调用 Action 类的 Action 方法,在调用 Action 方法之前,会将 ValueStack 对象顶层节点中的属性值赋给 Action 类中相应的属性。大家要注意,在这里就给我们带来了很大的灵活性。也就是说,在 Struts 2 调用拦截器的过程中,可以改变 ValueStack 对象中属性的值,当改变某个属性值后, Action 类的相应属性值就会变成在拦截器中最后改变该属性的这个值。

  从上面的描述很容易知道,在 Struts 2 Action 类可以获得与属性同名的参数值就是通过不同的拦截器来处理的,如获得请求参数的拦截器是 params ,获得 Action 的配置参数的拦截器是 staticParams 等。在这些拦截器内部读取相应的值,并更新 ValueStack 对象顶层节点的相应属性的值。而 ValueStack 对象就像一个传送带,将属性值从一个拦截器传到另一个拦截器 ( 当然,在这期间,属性值可能改变 ), 最后会传到 Action 对象,并将 ValueStack 对象中的属性的值终值赋给 Action 类的相应属性。

从上面的描述可以看出,当在拦截器中进行ValueStack传递的时候,属性值是可能改变,分析原因我们大概可以知道是这段代码:

  1. /**
  2.         * Set the properties
  3.         */ 
  4.        List<Category> cityList=systemService.getCategorySortList("city"); 
  5.        stack.set("cityList",cityList); 
  6.         
  7.        EhcacheVindicatorProxy proxy=new EhcacheVindicatorProxy("menu"); 
  8.        List<FrontMenu> frontMenuList=(List)proxy.get(FrontMenu.class, "frontmenus", "menus.xml"); 
  9.        stack.set("frontMenuList",frontMenuList); 
/**         * Set the properties         */        List<Category> cityList=systemService.getCategorySortList("city");        stack.set("cityList",cityList);                EhcacheVindicatorProxy proxy=new EhcacheVindicatorProxy("menu");        List<FrontMenu> frontMenuList=(List)proxy.get(FrontMenu.class, "frontmenus", "menus.xml");        stack.set("frontMenuList",frontMenuList);

影响了后续defaultStack对属性值的设置,所以我们应该将这段代码最后执行,那么怎么最后执行了,这里就要知道拦截器栈的执行顺序的知识了,在这里就不讲了,修改后是遮掩的:

  1. HttpServletRequest request=(HttpServletRequest)ActionContext.getContext().get(StrutsStatics.HTTP_REQUEST); 
  2.         OgnlValueStack stack=(OgnlValueStack)request.getAttribute("struts.valueStack"); 
  3.         
  4.         String result=invocation.invoke(); 
  5.           
  6.         /**
  7.          * Set the properties
  8.          */ 
  9.         List<Category> cityList=systemService.getCategorySortList("city"); 
  10.         stack.set("cityList",cityList); 
  11.          
  12.         EhcacheVindicatorProxy proxy=new EhcacheVindicatorProxy("menu"); 
  13.         List<FrontMenu> frontMenuList=(List)proxy.get(FrontMenu.class, "frontmenus", "menus.xml"); 
  14.         stack.set("frontMenuList",frontMenuList); 
  15.          
  16.         return result; 
HttpServletRequest request=(HttpServletRequest)ActionContext.getContext().get(StrutsStatics.HTTP_REQUEST);        OgnlValueStack stack=(OgnlValueStack)request.getAttribute("struts.valueStack");       String result=invocation.invoke();         /**         * Set the properties         */        List<Category> cityList=systemService.getCategorySortList("city");        stack.set("cityList",cityList);                EhcacheVindicatorProxy proxy=new EhcacheVindicatorProxy("menu");        List<FrontMenu> frontMenuList=(List)proxy.get(FrontMenu.class, "frontmenus", "menus.xml");        stack.set("frontMenuList",frontMenuList);                return result;

这样就可以保证不会干扰params之类的默认拦截器的执行。

这里要注意的是拦截器的执行顺序,如果设成这样:

  1. <!--引用默认拦截器--> 
  2. <interceptor-ref name="defaultStack" /> 
  3. <interceptor-ref name="properties" /> 
  4.                  
<!--引用默认拦截器--><interceptor-ref name="defaultStack" /><interceptor-ref name="properties" />

我们要设的值不会设置成功

当然在这里具体的原因我没有分析,只大略讲了一下

相关文章
|
18天前
|
消息中间件 存储 搜索推荐
深入理解栈和队列(二):队列
深入理解栈和队列(二):队列
33 0
|
1月前
【栈】数据结构栈的实现
【栈】数据结构栈的实现
|
1天前
|
C语言
数据结构中顺序栈的进栈和出栈用C语言表示
数据结构中顺序栈的进栈和出栈用C语言表示
10 1
|
11天前
|
存储 算法 调度
数据结构期末复习(3)栈和队列
数据结构期末复习(3)栈和队列
18 0
|
22天前
|
存储 缓存 算法
【算法与数据结构】栈的实现详解
【算法与数据结构】栈的实现详解
|
22天前
|
存储 算法 编译器
【数据结构】栈算法(算法原理+源码)
【数据结构】栈算法(算法原理+源码)
【数据结构】栈算法(算法原理+源码)
|
27天前
|
存储
【数据结构】什么是栈?
【数据结构】什么是栈?
28 0
【数据结构】什么是栈?
|
30天前
|
存储 设计模式 算法
【C/C++ 数据结构 线性表】深入理解与实现栈:从基础到应用的全面探索
【C/C++ 数据结构 线性表】深入理解与实现栈:从基础到应用的全面探索
52 0
|
1月前
|
存储
用队列和栈分别实现栈和队列
用队列和栈分别实现栈和队列
17 1
|
1月前
栈和队列的实现(详解+图解!文末附完整代码)
栈和队列的实现(详解+图解!文末附完整代码)
76 2