Struts2 --- ActionContext和ServletActionContext

一、ActionContext

 

我们知道,ActionContext是Action执行时的上下文,里面存放着Action在执行时需要用到的对象,也称之为广义值栈。Struts2在每次执行Action之前都会创建新的ActionContext,在同一个线程里ActionContext里面的属性是唯一的,这样Action就可以在多线程中使用。

 

1、Action的多例模式

Action对象的多例模式,示例如下:

 

import com.opensymphony.xwork2.ActionSupport;

public class HelloWorldAction extends ActionSupport{

	private static final long serialVersionUID = 1L;

	public HelloWorldAction(){
		System.out.println("create new HelloWorldAction");
	}
	
	// 默认调用方法
	public String execute() {

		System.out.println("hello world");
		return "index";
	}
}

 

<package name="helloworld" namespace="/" extends="struts-default">
        <action name="helloWorldAction" class="com.test.struts2.action.HelloWorldAction">
            <result name="index">index.jsp</result>
        </action>
    </package>

 

 

 

通过上面的示例可以看出,struts2采用的是多例模式,每次访问的时候都会创建一个新的HelloWorldAction

 

 

2、ActionContext的线程安全性

ActionContext的线程安全性,示例如下:

 

ThreadLocal又称为“线程局部变量”,它为每一个使用该变量的线程都提供一个变量值的副本,使每一个线程都可以独立地改变自己的副本,而不会和其它线程的副本冲突。存放在ActionContext里的数据都存放在这个ThreadLocal的属性中,而这个属性只会在对应的当前请求线程中可见,从而保证数据是线程安全的。

 

3、ActionContext中对象的Map包装

Struts2框架将与Web相关的很多对象重新进行了包装,比如将HttpSession对象重新包装成了一个Map对象,里面存放着Session中的数据,提供这个Map给Action使用,而不用Action直接和底层的HttpSession打交道。也正是因为框架的包装,让Action可以完全的和Web层解耦。示例:

 

SessionMap session = (SessionMap) ActionContext.getContext()
				.get(ServletActionContext.SESSION);
		System.out.println("SessionMap session = " + session.getClass().getName());


结果:

 

 

SessionMap session = org.apache.struts2.dispatcher.SessionMap

 

 

 

 

 

4、ActionContext的获取方式

(1)在自定义的拦截器中:使用ActionInvocation.getInvocationContext()或者使用ActionContext.getContext()

(2)在Action类中:让拦截器注入或者使用ActionContext.getContext()

(3)在非Action类中:让Action类传递参数、使用注入机制注入或者使用ActionContext.getContext()。注意:只有运行在request线程中的代码才能调用ActionContext.getContext(),否则返回的是null

 

5、ActionContext获取对象方式

(1)HttpServletRequest:请求对象

 

HttpServletRequest request = (HttpServletRequest) ActionContext.getContext()
				.get(ServletActionContext.HTTP_REQUEST);

 

 

 

(2)HttpServletResponse:响应对象

 

HttpServletResponse response = (HttpServletResponse) ActionContext.getContext()
				.get(ServletActionContext.HTTP_RESPONSE);


(3)SessionMap:session对象

 

 

 

 

SessionMap session = (SessionMap) ActionContext.getContext()
				.get(ServletActionContext.SESSION);


(4)ValueStack:值栈对象

 

 

ValueStack valueStack = (ValueStack) ActionContext.getContext()
				.get(ServletActionContext.VALUE_STACK);


(5)Parameters:参数对象

 

 

TreeMap parameters = (TreeMap) ActionContext.getContext().get(ServletActionContext.PARAMETERS);


(6)Application:应用

 

 

 

 

ApplicationMap application = (ApplicationMap) ActionContext.getContext()
					.get(ServletActionContext.APPLICATION);


(7)Local:当前环境

 

 

Locale locale = (Locale) ActionContext.getContext()
					.get(ServletActionContext.LOCALE);


(8)ActionMapping:ActionMapping的主要功能就是管理Action的信息和管理Action执行完成以后的ActionForward的信息。

 

 

ActionMapping action_mapping = (ActionMapping) ActionContext.getContext()
					.get(ServletActionContext.ACTION_MAPPING);


(9)DefaultActionInvocation:默认Action执行器

 

 

DefaultActionInvocation action_invocation = (DefaultActionInvocation) ActionContext.getContext()
				.get(ServletActionContext.ACTION_INVOCATION);

可以通过DefaultActionInvocation获取ActionContext:

 

 

ActionContext invocationContext = action_invocation.getInvocationContext();

 

 

 

二、ServletActionContext

这个类直接继承了ActionContext,当然也继承了它父类的很多功能,比如:对OgnlValueStack、Action名字等的访问。

 

更重要的是,它还提供了直接访问Servlet的相关对象的功能,它可以取得的对象有:

(1)HttpServletRequest:请求对象

 

HttpServletRequest request = ServletActionContext.getRequest();


(2)HttpServletResponse:响应对象

 

 

HttpServletResponse response = ServletActionContext.getResponse();


(3)ActionContext:Action上下文

 

 

ActionContext context = ServletActionContext.getContext();
		ActionContext actionContext = ServletActionContext.getActionContext(request);


(4)ActionMapping:ActionMapping的主要功能就是管理Action的信息和管理Action执行完成以后的ActionForward的信息。

 

 

ActionMapping actionMapping = ServletActionContext.getActionMapping();


(5)PageContext:Page上下文

 

 

PageContext pageContext = ServletActionContext.getPageContext();


(6)ServletContext:Servlet上下文

 

 

ServletContext servletContext = ServletActionContext.getServletContext();


(7)ValueStack:值栈

 

 

ValueStack valueStack = ServletActionContext.getValueStack(request);

 

 

 

 

 

三、ActionContext和ServletActionContext的联系

 

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

建议的原则是:

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

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

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值