jstl中${} 的查找顺序是page、request、session、application,找到了就返

解决方案 »

  1.   

    我说的是Struts2的ognl,Struts2默认支持JSTL吗?
      

  2.   

    struts2的actionContext,也就是ValueStack。是放在当前的线程中的,用threadlocal来存储。他和规范中的context(如:request)不一样。用#号可以到当前线程中的valueStack中获取相关的信息而$是jstl的标识,我认为应该不支持struts2。你的例子是session,这个是特殊机制,struts在set的时候就已经把内容放入和httpSession中了所以用jstl能获取。不过楼主可以测试一下
      

  3.   

    OGNL Context中的
    request
    application
    session 
    attr 
    parameters 
    这五个中的数据是绝对可以使用${}来获取的。至于ValueStack,不敢完全确定。
    印象中我曾用${}取过ValueStack(root)根对象中的数据,貌似也是可以的。不过,OGNL 比 JSP EL 强大多了,一般在Struts2中,都会使用 OGNL 的。
    所以,楼主问的这个问题,似乎没有多大意义……
    如果楼主想使用Struts2,就不必再留恋于 JSP EL 了,全心全意地使用 OGNL 吧,呵呵。
      

  4.   

    我刚试过了,用JSTL的${tip}可以访问Action中定义tip属性:private String tip,这是为什么?
      

  5.   

    用JSTL只能访问request、session、application中的属性,为什么在JSP页面用的${tip}可以访问Action中定义tip属性:private String tip;请教大家
      

  6.   

    用JSTL只能访问request、session、application中的属性,为什么在JSP页面用的${tip}可以访问Action中定义tip属性:private String tip;请教大家
      

  7.   


    错。
    EL是访问不到私有成员的。
    ${tip}是从作用域对象中获取到的值,确切地说,这里的作用域对象是request。不信的话,你可以这样验证:
    ${ requestScope.tip }
    或更直观的:
    <%= request.getAttribute( "tip" ) %>
      

  8.   


    别说 el,就是ognl也是不能的,谁也不能,这是原则问题!!
      

  9.   

    [接9楼]
    但如果你用 request.getAttributeNames() 去获取所有属性的名字,却是找不到“tip”这个名字的。
    关于这个奇怪现象,很久之前就发现了。但因为这个问题一则无关痛痒,二则资料上好像都没有说明,要搞懂的话估计得查看大量源代码,所以就一直搁那儿了。可以告诉楼主一点:Struts2是把值栈保存在 request 中的。你可以通过 request.getAttribute( "struts.valueStack" ); 得到它。
    估计 request.getAttribute( "tip" ) 能取到值可能跟它有关吧?
    想一想,真应该抽时间去搞懂这来龙去脉才行呢,呵呵。
      

  10.   

    但我测试可以。
    我在Action代码如下:
    public class Login extends ActionSupport{
    private String username;        public String getUsername() {
    return username;
    }
    public void setUsername(String username) {
    this.username= username;
    }
            …………在JSP页面中用${username}或${requestScope.username}可以访问到username的值。
      

  11.   

    经过我的分析研究,结论如下:其实数据是被存放在requestContext中的,而request对象及其session等对象又被放入了ActionContext中,通过ognl表达式是从ActionContext中获取requestContext里面存放的对象,而用jstl是直接从request中获取对象即:用jstl是直接获取,而用ognl是间接的从ActionContext中获取request对象中的数据ActionContext的解释如下:ActionContext中包含了大量的环境信息,包括:Locale、Application、Session、ValueStack等等。
      

  12.   


    是呀,这就是我要表达的意思。这里的username并非是Action的私有成员,而是request作用域中的值。EL访问的是get方法,是绝对不会访问成员变量的(无论公有还是私有)。请楼主再仔细看一遍我在8楼说的话:${tip}是不能访问私有成员的,它是从作用域对象中获取到的值,确切地说,这里的作用域对象是request。 你可以这样验证: 
    ${ requestScope.tip } 
    或更直观的: 
    <%= request.getAttribute( "tip" ) %>
      

  13.   


    13楼的结论很有道理,但是对回答楼主的问题没有丝毫意义吧?现在的问题不是EL与OGNL访问数据的方式的区别,而是:
    为什么值栈中的变量,可以被EL访问到?已知:
    request.getAttribute( "tip" ) 可以访问到数据。
    但如果你用 request.getAttributeNames() 去获取所有属性的名字,却是找不到“tip”这个名字的。
    Struts2是把值栈保存在 request 中的。你可以通过 request.getAttribute( "struts.valueStack" ); 得到它。 疑问:
    那么,"tip"所对应的数据,应该不是直接保存在request中?那么是从request中的值栈间接获取?
    如果是后者,那Struts2的过滤器是否对原有的request对象做了手脚,以致于它会自动访问值栈呢?(通过拦截器是可以很轻松实现这个目的的)现在看来,后者的可能性非常大。
    本周我除了要工作,还有考试任务,时间很紧。所以每天只回一帖,还不能花太多时间。呵呵。
    我一定会抽时间做个测试的。
      

  14.   

    [接14楼]
    看来楼主的理解与我的表达出现了偏差。这问题很严重,不得不再补充一下:我说的“
    你可以这样验证: 
    ${ requestScope.tip } 
    或更直观的: 
    <%= request.getAttribute( "tip" ) %>
    ”的用意是:通过这两者可以看到结果,那就说明数据是在request中。EL是从request中获得数据的,而不是访问的Action的成员变量(目的EL是绝对不会这么做的)。不怪楼主理解错误,是我的表达能力有待提高。TOT……
      

  15.   


    怎么么有意义?谁说值栈中的可以被jstl访问,怎么可能?你以为sun会来做struts2的接口嘛?
    变量不是存放在值栈中,而是存放在request的上下文中;用ognl也只是去访问值栈中存放的request,间接去访问request上下文中的信息。jstl---request context---value
    ognl---valueStack---request context--value如果楼上有意义,请说出根据!通过request可以获取struts.valueStack,那也只是说明这个对象也被放入到request而已。
      

  16.   

    [接15楼]
    刚才抽时间测试了一下,映证了我在15楼的猜测。Struts2会对request对象进行装饰,所用的类是org.apache.struts2.dispatcher.StrutsRequestWrapper 查看该类源码,发现它装饰了getAttribute()方法:    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);        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 && attribute == null && 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);
                }
            }
    结论:

    EL能访问到值栈中的内容。
    之所以能访问到,是因为EL可以访问request的getAttribute()方法,而此方法被Sturts2进行了装饰,可以访问到ActionContext,进而可以访问到值栈。
      

  17.   

    总结:
    OGNL Context中的 
    request 
    application 
    session 
    attr 
    parameters 
    这五个中的数据是绝对可以使用${}来获取的。
    另外,ValueStack中的数据也可以通过${}来获取,是通过装饰之后的request对象做到的。详见第5、9、15、16、18楼。问题算是彻底解决了,呵呵。最后再说一次。
    不过,OGNL 比 JSP EL 强大多了,一般在Struts2中,都会使用 OGNL 的。 
    而且 JSP 2.1 中,EL 与 OGNL 在“#”的使用上存在冲突,所以在 JSP 2.1 中使用Struts2的时候会禁用 EL 的。所以,楼主问的这个问题,似乎没有多大意义…… 
    如果楼主想使用Struts2,就不必再留恋于 JSP EL 了,全心全意地使用 OGNL 吧,呵呵。
      

  18.   

    楼上说对了,StrutsRequestWrapper类实现了HttpServletRequest接口,这是struts文档的解释
    All Struts requests are wrapped with this class, which provides simple JSTL accessibility. This is because JSTL works with request attributes, so this class delegates to the value stack except for a few cases where required to prevent infinite loops. Namely, we don't let any attribute name with "#" in it delegate out to the value stack, as it could potentially cause an infinite loop. For example, an infinite loop would take place if you called: request.getAttribute("#attr.foo").jstl会调用getAttribute,就会进入这个类,而这个类里面就能访问到ValueStack,进而实现了ognl和jstl访问同意空间学习到了!哈哈
      

  19.   

    谢谢大家的精彩回答。现在来总结一下:我的问题:为什么JSTL可以访问Action中的属性,如:
    private String tip;
    public String getTip(){
       return this.tip;
    }
    在JSP页面中可用${tip}访问到tip属性。
    总结一下accp206的答案:
    ①JSTL能访问Action中通过request.setAttribute("")设置的值。这是大家所熟悉的。②JSTL能访问Action中属性(通过getXXX方法实现访问)。
    因为ValueStack存在于request,所以用${tip}访问时的顺序是:request先访问ValueStack,ValueStack从中找出tip对应的值。对于这一点,期待accp206的测试。
      

  20.   

    看来我总结的晚了,呵呵。
    谢谢大家,特别是accp206
    结贴了