`
zhoutianzhe
  • 浏览: 48792 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

ognl中 带#的取值

阅读更多
package org.apache.struts2.dispatcher;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.util.ValueStack;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

public class StrutsRequestWrapper extends HttpServletRequestWrapper
{
  public StrutsRequestWrapper(HttpServletRequest req)
  {
    super(req);
  }

  public Object getAttribute(String s)
  {
    if ((s != null) && (s.startsWith("javax.servlet")))
    {
      return super.getAttribute(s);
    }

    ActionContext ctx = ActionContext.getContext();
    Object attribute = super.getAttribute(s);
    if ((ctx != null) && 
      (attribute == null)) {
      boolean alreadyIn = false;
      Boolean b = (Boolean)ctx.get("__requestWrapper.getAttribute");
      if (b != null) {
        alreadyIn = b.booleanValue();
      }

      if ((!alreadyIn) && (s.indexOf("#") == -1)) {
        try
        {
          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;
  }
}


这是struts2中StrutsRequestWrapper的源码
从  ((!alreadyIn) && (s.indexOf("#") == -1)
可以看出 如果ognl表达式中没有加"#" 如果在 parameter,request,session,application,attr 中没有找到对应的“属性”则会继续到ValueStack(root)中找。相反如果加了"#"则不会在ValueStack寻找。

比如:${#requestScope.name} 如果在request中没找到name则停止寻找,直接返回。
${requestScope.name} 如果在request中没找到name则会继续在ValueStatck中继续寻找。

补充:
OGNL是一个对象,属性的查询语言。在OGNL中有一个类型是Map的Context(称为上下文),在这个上下文中有一个跟元素(root),对跟元素的属性的访问可以直接使用属性名字,但是对于其他非跟元素的访问必须加上特殊符号#。

在Struts2中 上下文为ActionContext,根元素位Value Stack(值堆栈,值堆栈代表了一族对象而不是一个对象,其中Action类的实

例也属于值堆栈的一个)。ActionContext中的内容如下图:
|
|--application
|
|--session
context map---|
|--value stack(root)
|
|--request
|
|--parameters
|
|--attr (searches page, request, session, then application scopes)
|
因为Action实例被放在Value Stack中,而Value Stack又是根元素(root)中的一个,所以对Action中的属性的访问可以不使用标记#,而对其他的访问都必须使用#标记。

在JSP2.1中#被用作了JSP EL(表达式语言)的特殊记好,所以对OGNL的使用可能导致问题,
一个简单的方法是禁用JSP2.1的EL特性,这需要修改web.xml文 件:
<jsp-config>
<jsp-property-group>
<url-pattern>*.jsp</url-pattern>
<el-ignored>true</el-ignored>
</jsp-property-group>
</jsp-config>
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics