OGNL表达式

    |     2016年12月29日   |   struts2   |     0 条评论   |    1710

OGNL 全称 Object-Graph Navigation Language(对象图导航语言),用来获取和设置 Java 对象属性,需要写在 Struts2 标签里才生效。

它访问的对象都放在 OGNL 的 context 里。context 是 Map,存一组 key-value,实际对应 ActionContext。

Http 请求进到 Struts2 后,框架会创建 ActionContext、ValueStack 和对应的 Action;Action 放进 ValueStack,ValueStack 再放进 ActionContext。在 JSP 里访问 context 数据要用 #;ValueStack 是根对象,访问 Action 属性不用加 #。

一、OGNL 介绍

记住这条链就够用:

ognl 上下文(context) <=> ActionContext <- ValueStack <- action 对象

值栈 ValueStack 里常见对象:action 实例、request、session、application、response、parameters 数组、attr 等。

二、主要功能

  • 取数据:用一段很短的表达式取出各种数据。
  • 附带便捷能力:方法调用、静态方法和属性调用、数值运算等。

三、如何取数据

OGNL 从两个地方取数据:一是 Action 实例属性,二是 ValueStack(值栈)。会先从前一个取,取不到再到值栈。值栈里存了 request、session、application、response、action 实例、parameters 数组等。

1. 取 Action 实例的属性

Action 属性可以直接在 Struts2 标签里用属性名拿到,不要加 #:

<s:property value="name"/>
<s:property value="user.password"/>

2. 取 ValueStack 中的数据

Struts2 提供三种写法:#、%{}、${}。# 和 %{} 要放到 Struts2 标签里才生效:

<s:property value="#name"/>
<s:property value="%{'hello struts2'}"/>

% 的用途是:标签属性被当成字符串时,告诉运行环境 %{} 里是 OGNL 表达式:

<s:url value="%{#myMap['key1']}"/>

最常用的还是 #:

写法 含义
#session.name2 / #application.name3 取 session、application 里的 attribute,要加前缀
#name 取 request 范围 attribute,不要加 request 前缀(加上反而取不到);默认只从 request 取,不会自动再到 session / application
#parameters.name[0] 取请求参数,必须加 parameters,结果是数组,第一项加下标;相当于 request.getParameterValues(“name”)[0]
#attr.name 按 request → session → application 顺序找 attribute,找到就停
#{‘foo1′:’bar1’} 用 # 构造 Map
books.{?#this.price<100} 过滤和投影(projecting)集合
<s:property value="#session.name2"/>
<s:property value="#application.name3"/>
<s:property value="#name"/>
<s:property value="#parameters.name[0]"/>
<s:property value="#attr.name"/>

<s:set name="foobar" value="#{'foo1':'bar1', 'foo2':'bar2'}" />
<s:property value="#foobar['foo1']" />
<s:radio list="#{'0':'男','1':'女'}" name="sex" label="性别" value="%{user.sex}"></s:radio>

$ 有两种用途:国际化资源文件里引用 OGNL;以及在 Struts2 配置文件里引用:

<action name="saveUser" class="userAction" method="save">
    <result type="redirect">listUser.action?msg=${msg}</result>
</action>

四、代码实例

Action 侧往 context / 值栈里塞数据:

/**
 * 通过 ognl 表达式从 ognl 上下文(context)获取值显示到 jsp 页面
 * ognl 表达式只使用在 struts2 标签中
 * ognl 上下文(context) <=> ActionContext <- ValueStack <- action 对象
 *
 * 值栈 ValueStack 包含如下对象:
 * action 实例、request、session、application、response、parameters 数组  attr...
 */
public class OgnlAction extends BaseServletAction {
    private String name;
    private User user = new User();
    private List<User> list = new ArrayList<User>();

    @Override
    public String execute() throws Exception {
        ActionContext actionContext = ActionContext.getContext();
        ValueStack valueStack = actionContext.getValueStack();
        valueStack.push("ognl名称");

        name = "张三";
        user.setName("李四");
        user.setPassword("abcd");

        list.add(new User("王二", "456"));
        list.add(new User("小明", "123"));

        actionContext.put("number", "request=1001");
        session.setAttribute("age", "session=23");

        return SUCCESS;
    }

    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public User getUser() { return user; }
    public void setUser(User user) { this.user = user; }
    public List<User> getList() { return list; }
    public void setList(List<User> list) { this.list = list; }
}

JSP 侧对照取值:

<body>
    <!-- 显示 valuestack 值栈内容 -->
    <s:property value="name"/>
    <s:property value="user.name"/>
    <s:property value="user.password"/>

    <hr>
    <s:iterator value="list" var="u">
        <s:property value="#u.name"/><br>
    </s:iterator>

    <s:property value="#number"/>
    <s:property value="#session.age"/>

    <%-- ognl 从 action 对象中取属性值 --%>
    <s:property value="name" default="默认值" />
    <s:property value="user.username" default="默认值" />

    <br>用户名:
    <s:property value="userLists[1].username" default="默认值" />
    密码:
    <s:property value="userLists[1].password" default="默认值" />
    <br>
    <%-- ognl 从 ServletAPI request session .... 对象中取属性值 --%>
    <s:property value="#request.age" default="request默认值" />
    <s:property value="#session.sex" default="session默认值" />
    <!-- request > session > application -->
    <s:property value="#attr.age" default="attr默认值" />

    <%-- ognl 从 valueStack 中取属性值 --%>
    <s:property value="stack2.username" default="valueStack默认值" />

    ${stack2.password}
    <br> ${user.username}

    <br>
    <s:form action="ognltag.jsp" method="post">
        <s:textfield label="用户名" name="user_name"></s:textfield>
        <s:password label="密码" name="pass_word"></s:password>
        <s:submit value="提交"></s:submit>
    </s:form>

    <s:property value="#parameters.user_name"/>
    <s:property value="#parameters.pass_word"/>

    <s:debug></s:debug>
</body>

一句话总结:Action 属性直接写属性名,context 里的数据加 #;#session / #parameters / #attr 各管一层范围,%{} 只在标签属性被当成字符串时把 OGNL 打开。

转载请注明来源:OGNL表达式
本文链接地址:https://ai.zhousir.top/?p=1875

上一篇:

下一篇:

回复 取消