ActionContext表格总结

  用一张表格来总结:

 

 

变量 从ActionContext中获得 生命周期 用Ongl来读取值 使用ServletConfigInterceptor来注入
ActionContext类 静态方法ActionContext. getContext() 一次Http请求 使用“#”加上key,如“#name” 无法注入
ValueStack类 ActionContext. getValueStack() 一次Http请求 直接填写来访问栈中对象的方法,或者使用top来直接获得栈中对象 无法注入
HttpServletRequest类 ActionContext. get( StrutsStatics. HTTP_REQUEST) 一次Http请求 无方便的方法 实现ServletRequestAware接口
request的Map ActionContext. get("request") 一次Http请求 使用“#request”再加上key,如“#request.name”或者“#request['name']” 实现RequestAware接口
parameters的Map ActionContext. get( "parameters") 一次Http请求 使用“# parameters”再加上key,如“#parameters .name”或者“#parameters ['name']” 实现ParameterAware接口
HttpServletSession类 无(需通过HttpServletRequest来获得) 一次Http Session会话 无方便的方法 无法注入
session的Map ActionContext. get("session") 每次请求创建,但在一次Http Session会话中数据都是一样的 使用“#session”再加上key,如“# session.name”或者“#session ['name']” 实现SessionAware接口
ServletContext类 ActionContext. get( StrutsStatics. SERVLET_CONTEXT) 网站项目启动后一直存在且唯一 无方便的方法 使用ServletContextAware接口
application的Map ActionContext.get( "application") 每次请求时创建,但其中的数据是网站项目启动后一直存在且共享 使用“# application”再加上key,如“#application .name”或者“#application ['name']” 使用ApplicationAware接口

 

附录1 ActionContext中到底有哪些数据

 

key key的声明处 value的类型 value.toString()

com. opensymphony. xwork2. dispatcher.

HttpServletRequest

StrutsStatics. HTTP_REQUEST org. apache. struts2. dispatcher. StrutsRequestWrapper org. apache. struts2. dispatcher. StrutsRequestWrapper @10984e0
application org. apache. struts2. dispatcher. ApplicationMap
com. opensymphony. xwork2. ActionContext. locale ActionContext. LOCALE java. util. Locale zh_CN
com. opensymphony. xwork2. dispatcher. HttpServletResponse StrutsStatics. HTTP_RESPONSE org. apache. catalina. connector. ResponseFacade org. apache. catalina. connector. ResponseFacade @14ecfe8

xwork. NullHandler.

createNullObjects

  Boolean false
com. opensymphony. xwork2. ActionContext. name ActionContext. ACTION_NAME String index

com.opensymphony. xwork2.ActionContext.

conversionErrors

ActionContext.

CONVERSION_ERRORS

java. util. HashMap {}
com. opensymphony. xwork2. ActionContext. application ActionContext. APPLICATION org. apache. struts2. dispatcher. ApplicationMap
attr org. apache. struts2. util. AttributeMap org. apache. struts2. util. AttributeMap @133a2a8
com. opensymphony. xwork2. ActionContext. container ActionContext. CONTAINER com. opensymphony. xwork2. inject. ContainerImpl com. opensymphony. xwork2. inject. ContainerImpl @fc02c8
com. opensymphony. xwork2. dispatcher. ServletContext StrutsStatics. SERVLET_CONTEXT org. apache. catalina. core. ApplicationContextFacade org. apache. catalina. core. ApplicationContextFacade @11ad78c
com. opensymphony. xwork2. ActionContext. session ActionContext. SESSION org.apache.struts2. dispatcher.SessionMap {}

com.opensymphony. xwork2.ActionContext.

actionInvocation

ActionContext. ACTION_INVOCATION com. opensymphony. xwork2. DefaultActionInvocation com. opensymphony. xwork2. DefaultActionInvocation @13d4497
xwork. MethodAccessor. denyMethodExecution 笔者很懒,没有找 Boolean false
report. conversion. errors 笔者很懒,没有找 Boolean false
session org. apache. struts2. dispatcher. SessionMap {}
com. opensymphony. xwork2. util. ValueStack. ValueStack ValueStack.VALUE_STACK com. opensymphony. xwork2. ognl. OgnlValueStack com. opensymphony. xwork2. ognl. OgnlValueStack @16237fd
request org. apache. struts2. dispatcher. RequestMap
action 笔者很懒,没有找 com. example. MyAction
struts. actionMapping 笔者很懒,没有找 org. apache. struts2. dispatcher. mapper. ActionMapping org. apache. struts2. dispatcher. mapper. ActionMapping @892cc5
parameters java. util. HashMap {}
com. opensymphony. xwork2. ActionContext. parameters ActionContext.PARAMETERS java. util. TreeMap {}

 

注意:该表格为了排版在某些地方加了空格。

 

可以看出,有些相同的对象被以不同的key多次设置到ActionContext中。如果想看看创建ActionContext的源代码,请看org.apache.struts2.dispatcher.Dispatcher的serviceAction方法和两个createContextMap方法。

附录2 Struts2标签中value属性直接对ActionContext访问的问题

    经试验并查看相关源代码后发现,在使用<s:property value="..."/>时,该标签的执行类会先根据value中表达式到值栈中执行表达式来查找值。如果在值栈中找到值,就返回该值;如果没有找到,则把该表达式作为ActionContext的key,到ActionContext中去找值。比如<s:property value="request"/>也会得到ActionContext中的request,等价于<s:property value="#request"/>。但是,由于标签的执行类会认为该值时String类型的,并且会直接进行类型转换。于是,如果直接使用<s:property value="request"/>的话其实会让页面抛出异常:Request类型不能转换成String类型。所以,只能用如果不带#的话只能成功读取ActionContext中String类型的值。这种机制使得某些时候栈顶的属性可以覆盖ActionContext中的key,或许你正需要它。然而,鉴于这种机制的不确定性,笔者建议访问ActionContext中的数据一定要带上“#”,可以免去一些麻烦。

    关于这种转型异常,笔者认为是Struts2的bug,源代码如下,当“value = getValue(expr, asType);”时,是考虑了asType的,但从context中读取时“value = findInContext(expr);”,就没有考虑asType,并且没有在其他地方看到类型检查操作:

 

 

Java代码 复制代码 收藏代码
  1. // 本代码截取Struts2.3.1.2版本com.opensymphony.xwork2.ognl.OgnlValueStack类的第340行-352行 
  2.     private Object tryFindValue(String expr, Class asType) throws OgnlException {  
  3.         Object value = null;  
  4.         try {  
  5.             expr = lookupForOverrides(expr);  
  6.             value = getValue(expr, asType);  
  7.             if (value == null) {  
  8.                 value = findInContext(expr);  
  9.             }  
  10.         } finally {  
  11.             context.remove(THROW_EXCEPTION_ON_FAILURE);  
  12.         }  
  13.         return value;  
  14.     } 
  1. // 本代码截取Struts2.3.1.2版本com.opensymphony.xwork2.ognl.OgnlValueStack类的第340行-352行 
  2.     private Object tryFindValue(String expr, Class asType) throws OgnlException { 
  3.         Object value = null; 
  4.         try { 
  5.             expr = lookupForOverrides(expr); 
  6.             value = getValue(expr, asType); 
  7.             if (value == null) { 
  8.                 value = findInContext(expr); 
  9.             } 
  10.         } finally { 
  11.             context.remove(THROW_EXCEPTION_ON_FAILURE); 
  12.         } 
  13.         return value; 
  14.     } 

posted on 2014-09-09 15:34  锟斤拷锟斤拷  阅读(328)  评论(0编辑  收藏  举报

导航