在web开发中ActionContext和ServletActionContext的比较

架构设计 专栏收录该内容
8 篇文章 0 订阅

1.ActionContext

ActionContext(com.opensymphony.xwork.ActionContext)是Action执行时的上下文,上下文可以看作是一个容器(其实我们这里的容器就是一个Map而已),它存放的是Action在执行时需要用到的对象。也称之为广义值栈。Struts2在每次执行Action之前都会创建新的ActionContext,在同一个线程里ActionContext里面的属性是唯一的,这样Action就可以在多线程中使用。

   Struts2在每次执行Action之前都会创建新的ActionContext,在同一个线程里ActionContext里面的属性是唯一的,这样Action就可以在多线程中使用。

actionContext对象的创建过程是

<span style="font-size:14px;">static ThreadLocal actionContext = new ActionContextThreadLocal()。</span>
ActionContextThreadLocal是实现ThreadLocal的一个内部类。ThreadLocal可以命名为"线程局部变量",它为每一个使用该变量的线程都提供一个变量值的副本,使每一个线程都可以独立地改变自己的副本,而不会和其它线程的副本冲突。这样ActionContext里的属性只会在对应的当前请求线程中可见,从而保证它是线程安全的。

1.1.ActionContext的线程安全性

ThreadLocal又称为“线程局部变量”,它为每一个使用该变量的线程都提供一个变量值的副本,使每一个线程都可以独立地改变自己的副本,而不会和其它线程的副本冲突。

存放在ActionContext里的数据都存放在这个ThreadLocal的属性中,而这个属性只会在对应的当前请求线程中可见,从而保证数据是线程安全的。

1.2.通过ActionContext取得相关对象

取得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>

2.ServletActionContext概述

在实际应用开发中,光是获取数据就够了吗?答案显然是否定的,有些时候,根据功能需要,在Action中必须要能获取到Servlet相关的API,比如要操作Cookie。这个时候,就需要用ServletActionContext了。

2.1 ServletActionContext概述

  这个类直接继承了ActionContext,当然也继承了它父类的很多功能,比如:对OgnlValueStack、Action名字等的访问。更重要的是,它还提供了直接访问Servlet的相关对象的功能,它可以取得的对象有:

  • HttpServletRequest:请求对象
  • HttpServletResponse:响应对象
  • ServletContext:Servlet上下文信息
  • PageContext:Http页面上下文

2.2 基本使用

HttpServletRequest request = ServletActionContext.getRequest();  
HttpServletResponse response = ServletActionContext.getResponse();  
ServletContext servletContext = ServletActionContext.getServletContext();  
PageContext pageContext = ServletActionContext.getPageContext();  
HttpSession session = ServletActionContext.getRequest().getSession();  

  这里要注意的是HttpSession对象的获取,是在取得HttpRequest对象过后,通过HttpRequest对象来获取会话对象。当然,取得相应的对象后,就直接使用这些对象的方法来进行开发,这里就不去赘述了。

2.3 通过IoC/DI的方式来获取相应的Servlet对象

  还可以通过IoC/DI的方式来获取相应的Servlet对象,对应关系是:

  • ServletRequestAware:通过这个接口来获取HttpServletRequest对象
  • ServletResponseAware:通过这个接口来获取HttpServletResponse对象

  用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,这里就不去赘述了。

3. ActionContextServletActionContext

  根据前面的讲述,你会发现,ActionContext和ServletActionContext有着一些重复的功能,都能够获取到Web对象的数据,但是又有些不同。通常情况下,可以这么认为:ActionContext主要负责值的操作;ServletActionContext主要负责获取Servlet对象。那么在Action中,该如何去抉择呢?建议的原则是:

  • 优先使用ActionContext
  • 只有ActionContext不能满足功能要求的时候,才使用ServletActionContext

  总之,要尽量让Action与Web无关,这对于Action的测试和复用都是极其有好处的。另外还有一点需要注意:在使用ActionContext时,不要在Action的构造函数里使用ActionContext.getContext(),因为这个时候ActionContext里的一些值也许还没有设置,这时通过ActionContext取得的值也许是null。


  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 打赏
    打赏
  • 扫一扫,分享海报

表情包
插入表情
评论将由博主筛选后显示,对所有人可见 | 还能输入1000个字符
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页

打赏作者

DYanchao2015

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值