获取Struts中值栈数据
在action中的实例变量,没有向EL表达式支持的域添加数据,却能在jsp中用EL表达式取出,是因为在struts2中使用的request被增强了
public class StrutsRequestWrapper extends HttpServletRequestWrapper {
/**
* The constructor
* @param req The request
*/
public StrutsRequestWrapper(HttpServletRequest req) {
super(req);
}
/**
* Gets the object, looking in the value stack if not found
*
* @param s The attribute key
*/
public Object getAttribute(String s) {
if (s != null && s.startsWith("javax.servlet")) {
// don't bother with the standard javax.servlet attributes, we can short-circuit this
// see WW-953 and the forums post linked in that issue for more info
return super.getAttribute(s);
}
ActionContext ctx = ActionContext.getContext();
Object attribute = super.getAttribute(s);
if (ctx != null) {
if (attribute == null) {
boolean alreadyIn = false;
Boolean b = (Boolean) ctx.get("__requestWrapper.getAttribute");
if (b != null) {
alreadyIn = b.booleanValue();
}
// note: we don't let # come through or else a request for
// #attr.foo or #request.foo could cause an endless loop
if (!alreadyIn && s.indexOf("#") == -1) {
try {
// If not found, then try the ValueStack
ctx.put("__requestWrapper.getAttribute", Boolean.TRUE);
ValueStack stack = ctx.getValueStack();
if (stack != null) {
attribute = stack.findValue(s);
}
} finally {
ctx.put("__requestWrapper.getAttribute", Boolean.FALSE);
}
}
}
}
return attribute;
}
}
在增强方法中,我们可以看到,程序会先从request中读取key对应的数据,如果存在数据,直接返回attribute
ActionContext ctx = ActionContext.getContext();
Object attribute = super.getAttribute(s);
如果没有数据,会从值栈中查询对应key的值,返回attribute
ValueStack stack = ctx.getValueStack();
if (stack != null) {
attribute = stack.findValue(s);
}