本帖最后由 iwieijakdf 于 2014-01-07 08:16:12 编辑

解决方案 »

  1.   

    #是访问非根对象,也就是非栈值数据,如ognl上下文和action上下文。#可以理解为ActionContext.getContext()。
    EL表达式,比如${username},相当于request.getParameter(username),然后你就去理解request什么意思就可以了。
      

  2.   

    <s:iterator value="#pdList">这句话是将每一次遍历的集合中的单个元素依次放在栈顶,el表达式也是直接从值栈中取值,所以就取到了额
      

  3.   

    楼主这个问题,为什么用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) {
                        alreadyIn = b.booleanValue();
                    }
                    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;
        }