struts2中actionContext().put到底把东西放哪了

本文探讨了Struts2框架中EL表达式的解析过程,特别是如何从不同的作用域检索属性值,包括request、session及valueStack。文章还详细解释了ActionContext的作用,以及如何通过装饰模式对HttpServletRequest进行扩展以实现EL表达式的定制化行为。

ActionContext.getContext().put(key,value);这个方法是以键值对的方式添加进去的
取出来直接根据key取:<%Object value = ActionContext.getContext().get(key)%>取得key对应的value

这个应该是Struts2里面的内容,那些封装成Map形式的 如session 、request等对象就是绑定到ActionContext对象上


在一个action中,有一个属性test, private String test; execute方法如下: public String execute() throws Exception { test = "vs_test"; ActionContext.getContext().put("test", "actionContext_test"); return "success"; } 在页面中使用下面两种方法输出: ${requestScope.test} <%= ActionContext.getContext().get("test") %> 如果把execute()方法中 test = "vs_test"; 注释掉; 输出结果为: actionContext_test actionContext_test action中赋值都没有使用 request.setAttribute()进行赋值,

根据资料 ${requestScope.test} 会先通过 request.getAttribute()取值,如果取不到则从 valueStack 中去,

根据第一次的输出结果,可以看出 test 在 valueStack 中的值为 vs_test,通过 <s:debug/> 也可以看出,

根据第二次的输出结果,可以看出 ActionContext.getContext().put("test", "actionContext_test") 也是把值放到 valueStack 中了,

但为什么第一次两种输出方式的输出值不一样哪?

 

另外如果我在execute()方法中放入以下代码:

ActionContext.getContext().getValueStack().set("test""hello");

${requestScope.test }的 输出结果变成了 hello,

此时在<s:debug/>中 可以看到作为当前action对象属性的test ,其值仍为

v 但是没有我手动放进去的 test,
actionContext.getContext().put()就是把属性放到action上下文中,这个actionContext本身 就是一个Map,里面放有默认的Map session等常用属性,比如可以actionContext.getContext().get(StrutsStatics.HTTP_REQUEST)得到struts2为我们action保存的HttpServletRequest对象 ,而你Put一个put("test", "actionContext_test"),放的就是一个String对象 。而el表达式能取到action的属性,是由于struts拦截了request.getAttribute()方法并重新实现了它,如果HttpServletRequest没有我们要的属性,就从actionContext中找我们Put的对象 ,再没有就找valuestack中找,所有你后面把自定义 的test放到值栈中去了,就把本身action中的test属性盖了,el就只能找到这个hello了。
可以参考 下面:
我们知道,JSTL默认是从page,request,session,application这四个Scope逐次查找相应的EL表达式所对应的对象的值。那么如果要使用JSTL来读取Action中的变量,就需要把Action中的变量,放到request域中才行。所以,早在 Webwork2.1.X的年代,我们会编写一个拦截器来做这个事情的。大致的原理是:在Action执行完返回之前,依次读取Action中的所有的变量,并依次调用request.setAttribute()来进行设置。具体的整合方式,请参考以下这篇文档:http://wiki.opensymphony.com/display/WW/Using+WebWork+and+XWork+with+JSP+2.0+and+JSTL+1.1 

不过随着时代的发展,上面的这种方式,已经不再被推荐使用了。(虽然如此,我们依然可以学习它的一个解决问题的思路)目前来说,自从Webwork2.2以后,包括Struts2,都使用另外一种整合方式:对HttpServletRequest进行装饰。让我们来看一下源码:

 

Java代码 

1. public class StrutsRequestWrapper extends HttpServletRequestWrapper {   

2.   

3.       

7.     public StrutsRequestWrapper(HttpServletRequest req) {   

8.         super(req);   

9.     }   

10.   

11.       

16.     public Object getAttribute(String s) {   

17.         if (s != null && s.startsWith("javax.servlet")) {   

18.             // don't bother with the standard javax.servlet attributes, we can short-circuit this   

19.             // see WW-953 and the forums post linked in that issue for more info   

20.             return super.getAttribute(s);   

21.         }   

22.   

23.         ActionContext ctx = ActionContext.getContext();   

24.         Object attribute = super.getAttribute(s);   

25.   

26.         boolean alreadyIn = false;   

27.         Boolean b = (Boolean) ctx.get("__requestWrapper.getAttribute");   

28.         if (b != null) {   

29.             alreadyIn = b.booleanValue();   

30.         }   

31.   

32.         // note: we don't let # come through or else a request for   

33.         // #attr.foo or #request.foo could cause an endless loop   

34.         if (!alreadyIn && attribute == null && s.indexOf("#") == -1) {   

35.             try {   

36.                 // If not found, then try the ValueStack   

37.                 ctx.put("__requestWrapper.getAttribute", Boolean.TRUE);   

38.                 ValueStack stack = ctx.getValueStack();   

39.                 if (stack != null) {   

40.                     attribute = stack.findValue(s);   

41.                 }   

42.             } finally {   

43.                 ctx.put("__requestWrapper.getAttribute", Boolean.FALSE);   

44.             }   

45.         }   

46.         return attribute;   

47.     }   

}

ActionContext.getContext().put(key,value);这个方法是以键值对的方式添加进去的
取出来直接根据key取:<%Object value = ActionContext.getContext().get(key)%>取得key对应的value

这个应该是Struts2里面的内容,那些封装成Map形式的 如session 、request等对象就是绑定到ActionContext对象上

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值