日期:2014-05-18  浏览次数:20706 次

【新人救助】EL表达式为什么可以在值栈中取值
本帖最后由 iwieijakdf 于 2014-01-07 08:16:12 编辑
我在后台将一个对象的list集合放到了值栈的Map栈中

public String getLastVersionPD(){
ActionContext.getContext().put("pdList", this.pdManager.getLastVersonPD());
return "listAction";
}

然后在前台用OGNL表达式迭代

<s:iterator value="#pdList">
  <s:property value="name"/>
  <s:property value="version"/>
  <s:a action="pdManagerAction_delete?key=%{key}">删除</s:a>
  <a href="javascript: showProcessImage('${requestScope.deploymentId}')">查看流程图</a>
</s:iterator>

name version key deploymentId都是一个对象的属性,迭代时是放在值栈的对象栈的顶部的,前边的name version key使用OGNL表达式能在值栈的对象栈取到值,为什么使用EL表达式也可以在request作用域取得deploymentId属性呢

------解决方案--------------------
楼主这个问题,为什么用el取request范围的东西会同样取到值栈的内容呢.这个问题就要结合struts2的源码来说了,我们知道request在javaee里面是HttpServletRequest它是一个接口里面的一切包装都是通过javax.servlet.http.HttpServletRequestWrapper类来实现的.struts2有自己的javax.servlet.http.HttpServletRequestWrapper实现,也就是在struts2-core包下的org.apache.struts2.dispatcher.StrutsRequestWrapper重新对getAttribute方法进行了重写.
我们知道el表达式取request范围的值就是调用request.getAttribute(String s);
一下这段是struts2的org.apache.struts2.dispatcher.StrutsRequestWrapper对getAttribute方法重写的源码部分

public Object getAttribute(String s) {
        if (s != null && s.startsWith("javax.servlet")) {
            //如果是${requestScope.javax.servlet.属性名的}就直接去request里面取值
            return super.getAttribute(s);
        }
//关键在下面,先从request里面取值取不到时就从值栈里面取值,所以就可以解释楼主这个为啥也能取到值了
        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) {