标签:
Struts2在每次执行Action之前都会创建新的ActionContext,在同一个线程里ActionContext里面的属性是唯一的,这样Action就可以在多线程中使用。
actionContext对象的创建过程是
<span style="font-size:14px;">static ThreadLocal actionContext = new ActionContextThreadLocal()。</span>ActionContextThreadLocal是实现ThreadLocal的一个内部类。ThreadLocal可以命名为"线程局部变量",它为每一个使用该变量的线程都提供一个变量值的副本,使每一个线程都可以独立地改变自己的副本,而不会和其它线程的副本冲突。这样ActionContext里的属性只会在对应的当前请求线程中可见,从而保证它是线程安全的。
ThreadLocal又称为“线程局部变量”,它为每一个使用该变量的线程都提供一个变量值的副本,使每一个线程都可以独立地改变自己的副本,而不会和其它线程的副本冲突。
存放在ActionContext里的数据都存放在这个ThreadLocal的属性中,而这个属性只会在对应的当前请求线程中可见,从而保证数据是线程安全的。
取得session:Map session = ActionContext.getContext().getSession();
取得request:Map request = (Map)ActionContext.getContext().get("request");
在Action中取得request请求参数"username"的值:
若有一个提交过来的username,那么通过param.get("username")可以取值。值得注意的是param.get("username")是一个String数组,Struts就是这样设计的。既然是String数组就需要这样取值:
<span style="font-size:14px;">String value[] = (String[])param.get("username"); String username = ""; for(int i=0;i<value.length;i++) { username +=value[i]; }</span>
这个类直接继承了ActionContext,当然也继承了它父类的很多功能,比如:对OgnlValueStack、Action名字等的访问。更重要的是,它还提供了直接访问Servlet的相关对象的功能,它可以取得的对象有:
HttpServletRequest request = ServletActionContext.getRequest(); HttpServletResponse response = ServletActionContext.getResponse(); ServletContext servletContext = ServletActionContext.getServletContext(); PageContext pageContext = ServletActionContext.getPageContext(); HttpSession session = ServletActionContext.getRequest().getSession();
这里要注意的是HttpSession对象的获取,是在取得HttpRequest对象过后,通过HttpRequest对象来获取会话对象。当然,取得相应的对象后,就直接使用这些对象的方法来进行开发,这里就不去赘述了。
还可以通过IoC/DI的方式来获取相应的Servlet对象,对应关系是:
用ServletRequestAware来示例一下。
(1)修改Action,让其实现ServletRequestAware接口,示例代码如下:
public class OgnlAction extends ActionSupport implements ServletRequestAware{ private HttpServletRequest request = null; public void setServletRequest(HttpServletRequest request) { this.request = request; } public String execute(){ request.setAttribute("request", "Request的属性值"); request.getSession().setAttribute("sessionTestKey", "测试SessionAware"); return this.SUCCESS; } }
(2)对应的结果页面也需要稍作修改,要把Action中设置的值显示出来,示例如下:
<%@ taglib prefix="s" uri="/struts-tags"%> Request的属性值:<s:property value="#request['request']"/> <br> 会话的属性值:<s:property value="#session['sessionTestKey']"/>
当然,你也可以以同样的方式去使用ServletResponseAware,这里就不去赘述了。
根据前面的讲述,你会发现,ActionContext和ServletActionContext有着一些重复的功能,都能够获取到Web对象的数据,但是又有些不同。通常情况下,可以这么认为:ActionContext主要负责值的操作;ServletActionContext主要负责获取Servlet对象。那么在Action中,该如何去抉择呢?建议的原则是:
总之,要尽量让Action与Web无关,这对于Action的测试和复用都是极其有好处的。另外还有一点需要注意:在使用ActionContext时,不要在Action的构造函数里使用ActionContext.getContext(),因为这个时候ActionContext里的一些值也许还没有设置,这时通过ActionContext取得的值也许是null。
在web开发中ActionContext和ServletActionContext的比较
标签:
原文地址:http://blog.csdn.net/heart_2015/article/details/51334022