Struts2值栈

本文记录Java学习过程中遇到的Struts2的值栈~

在Struts2的值栈中包括两部分,即值栈和上下文对象。

Context:即OgnlContext上下文,它是一个map结构,上下文中存储了一些引用(parameters、request、session和application等),上下文的Root为CompoundRoot。常见的引用如下:

  • parameters:该Map中包含当前请求的请求参数;
  • request:该Map中包含当前request对象中的所有属性;
  • session:该Map中包含当前session对象中的所有属性;
  • application:该Map中包含当前application对象中的所有属性;
  • attr:该Map按如下顺序来检索某个属性:request>session>application。

CompoundRoot:存储了action实例,它作为OgnlContext的Root对象。它继承ArrayList实现压栈和出栈功能,拥有栈的特点(先进后出,后进先出),最后压进栈的数据在栈顶,被称为对象栈。

Struts2对原OGNL作出的改进就是Root使用CompoundRoot(自定义栈),使用OgnlValueStack的findValue方法可以在CompoundRoot中从栈顶向栈底找查找的对象的属性值。

CompoundRoot作为OgnlContext的Root对象,并且在CompoundRoot中action实例位于栈顶,当读取action的属性值时会先从栈顶对象中找对应的属性,如果找不到则继续找栈中的其他对象,如果找到则停止查找。

ActionContext与ValueStack的关系

示例代码(源码):

public ActionContext createActionContext(HttpServletRequest request, HttpServletResponse response) {
	ActionContext ctx;
	Integer counter = 1;
	Integer oldCounter = (Integer)request.getAttribute(CLEANUP_RECURSION_COUNTER);
	if (oldCounter != null) {
		counter = oldCounter + 1;
	}

	ActionContext oldContext= ActionContext.getContext();
	if (oldContext != null) {
		ctx = new ActionContext(new HashMap<String, Object>(oldContext.getContextMap()));
	} else {
		ValueStack stack = dispatcher.getContainer().putAll(dispatcher.createContextMap(request, response, null));
		ctx = new ActionContext(stack.getContext());
	}
	request.setAttribute(CLEANUP_RECURSION_COUNTER, counter);
	ActionContext.setContext(ctx);
	return ctx;
}

在创建ActionContext的时候,创建ValueStack的对象,将ValueStack对象给ActionContext;ActionContext中有一个ValueStack的引用;ValueStack中也有一个ActionContext的引用;ActionContext获取ServletAPI的时候依赖值栈。

示例代码:

// 通过ActionContext对象获取值栈
ValueStack stack = ActionContext.getContext().getValueStack();

// 通过request域获取值栈
ValueStack stack = (ValueStack) ServletActionContext.getRequest().getAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY);

// 通过Action中属性提供的set/get方法操作值栈:因为Action本身在值栈中,Action中的属性也就默认在值栈中了,所以我们可以通过对Action的属性提供set/get方法的方式来操作值栈。

// 手动操作值栈:调用值栈的push和set方法对值栈进行操作。

标签: none