为什么EL表达式能访问struts2的值栈 struts2值栈详解

简单地说,struts2对默认的request进行了包装,默认会先从原request里面找,如果找不到,会从值栈里面找;

实现细节如下:

StrutsPrepareAndExecuteFilter在doFilter()时候,调用PrepareOperations的wrapRequest()方法;最终调用了Dispatcher的wrapRequest()方法;

// Dispatcher的wrapRequest()方法

public HttpServletRequest———— wrapRequest(HttpServletRequestrequest, ServletContext servletContext) throws IOException {
// don't wrap more than once
if (request instanceof StrutsRequestWrapper) {
return request;
}

String content_type = request.getContentType();
if (content_type != null &&content_type.indexOf("multipart/form-data") != -1) {
MultiPartRequest mpr = null;
//check for alternate implementations of MultiPartRequest
Set<String> multiNames =getContainer().getInstanceNames(MultiPartRequest.class);
if (multiNames != null) {
for (String multiName : multiNames) {
if (multiName.equals(multipartHandlerName)) {
mpr = getContainer().getInstance(MultiPartRequest.class,multiName);
}
}
}
if (mpr == null ) {
mpr = getContainer().getInstance(MultiPartRequest.class);
}
request = new MultiPartRequestWrapper(mpr, request,getSaveDir(servletContext));
} else {
request = new StrutsRequestWrapper(request);
}

return request;
}

StrutsRequestWrapper构造器会修改父类HttpServletRequestWrapper的父类ServletRequestWrapper的指针,视其指向StrutsRequestWrapper这个实例;

// 源码如下:

public class StrutsRequestWrapper extendsHttpServletRequestWrapper {


publicStrutsRequestWrapper(HttpServletRequest req) {
super(req);
}


publicObject getAttribute(String s) {
if (s != null &&s.startsWith("javax.servlet")) {
// don't bother with the standard javax.servlet attributes, we canshort-circuit this
// see WW-953 and the forums post linked in that issue for moreinfo
return super.getAttribute(s);
}

ActionContext ctx = ActionContext.getContext();
Object attribute = super.getAttribute(s); // 先从原request中取
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;
为什么EL表达式能访问struts2的值栈 struts2值栈详解
}
}

这样在页面上使用<%=request.getAttribute("xxx")%>可以访问到值栈的数据,el表达式可以访问到page、request、session、application范围的数据,所以可以访问到struts2的值栈;

  

爱华网本文地址 » http://www.aihuau.com/a/25101015/244713.html

更多阅读

手机如何访问电脑的共享文件 手机共享win10电脑文件

手机如何访问电脑的共享文件——简介 如果你的电脑里下载了很多精彩的电影,但是你嫌坐在电脑前太累,于是你想用手机或其他移动设备躺在床上看,但是这些设备内存有限,而且拷来拷去十分麻烦,那么有没有一种简单易行的方法呢? 我们知道电脑

隔夜茶为什么不能喝 过夜的茶叶水能喝吗

隔夜茶为什么不能喝——简介隔夜茶并不适合人体长期饮用,极有可能造成一些健康问题,很多朋友不清楚其中的科学依据和原因,那么,隔夜茶为什么不能喝呢?请看详解。隔夜茶为什么不能喝——隔夜茶为什么不能喝隔夜茶为什么不能喝 1、可能造

iOSUIAppearance使用详解 ios tag 值使用详解

iOS5及其以后提供了一个比较强大的工具UIAppearance,我们通过UIAppearance设置一些UI的全局效果,这样就可以很方便的实现UI的自定义效果又能最简单的实现统一界面风格,它提供如下两个方法。+(id)appearance这个方法是统一全部改,比如

详解买房时建筑面积与套内面积的区别 建筑面积计算实例详解

房地产商很多时候就靠这两个面积的转换来骗人,虽然现在还不到买房的时候,但是先搞清楚准备着,给自己提个醒:建筑面积包括套内面积。而套内面积包括套内使用面积和套内建筑面积。套内使用面积、墙体面积、阳台面积、公摊面积总和为房屋

焊接方法详解 氩弧焊的鱼鳞焊接技巧

焊接方法详解——简介焊接焊接是被焊工件的材质(同种或异种),通过加热或加压或两者并用,并且用或不用填充材料,使工件的材质达到原子间的建和而形成永久性连接的工艺过程。焊接方法详解——工具/原料焊接的方式焊接方发详解焊接方法详

声明:《为什么EL表达式能访问struts2的值栈 struts2值栈详解》为网友七月流裳百日还分享!如侵犯到您的合法权益请联系我们删除