Struts2(8)之OGNL表达式

Struts2(8)之OGNL表达式

微信搜索 zze_coding 或扫描 👉 二维码关注我的微信公众号获取更多资源推送:

概述

OGNL 是 Object-Graph Navigation Language 的缩写,它是一种第三方的、功能强大的表达式语言,通过它简单一致的表达式语法,可以存取对象的任意属性,调用对象的方法,遍历整个对象的结构图,实现字段类型转化等功能。它使用相同的表达式去存取对象的属性。

OGNL : 对象图导航语言,比 EL 表达式强大很多。

  • EL:从 11 个隐式对象中取值。
  • OGNL:可调用对象的方法,获取 Struts2 中值栈的数据。

简单使用

Java 工程下使用

现有如下 POJO:

// com.zze.bean.User

import java.util.Date;

public class User {
    private String name;
    private Integer age;
    private Date birthday;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", birthday=" + birthday +
                '}';
    }
}

调用对象方法

// 获得 context
OgnlContext context = new OgnlContext();
// 获得根对象
Object root = context.getRoot();
Object value = Ognl.getValue("'hello Struts2'.length()", context, root);
System.out.println(value);

/*
13
 */

调用静态方法

// 获得 context
OgnlContext context = new OgnlContext();
// 获得根对象
Object root = context.getRoot();
// 执行表达式:@类名@方法名
Object value = Ognl.getValue("@java.lang.Math@random()", context, root);
System.out.println(value);
/*
0.6367826736345159
 */

访问 Root 中的数据

// 获得 context
OgnlContext context = new OgnlContext();
User user = new User();
user.setName("张三");
user.setAge(12);
context.setRoot(user);
// 表达式直接写放入 root 中对象的属性名称即可取到对应属性名的值
Object name = Ognl.getValue("name", context, context.getRoot());
Object age = Ognl.getValue("age", context, context.getRoot());
System.out.println(name);
System.out.println(age);
System.out.println(age.getClass());
/*
张三
class java.lang.Integer
 */

访问 context 中的数据

// 获得 context
OgnlContext context = new OgnlContext();
User user = new User();
user.setName("张三");
user.setAge(12);
context.put("user", user);
// 表达式直接写放入 context 中 #key 即可取到对应值
Object name = Ognl.getValue("#user.name", context, context.getRoot());
Object age = Ognl.getValue("#user.age", context, context.getRoot());
System.out.println(name);
System.out.println(age);
/*
张三
 */

Struts2中通过标签使用

访问对象方法&静态方法

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
    <title>Test</title>
</head>
<body>
<%--访问对象方法--%>
<s:property value="'hello Struts2'.length()"/>

<hr>

<%--
访问静态方法
需要设置常量:struts.ognl.allowStaticMethodAccess = true
--%>
<s:property value="@java.lang.Math@random()"/>
</body>
</html>

特殊符号

# 号

# 号可以用来获取值栈中 context 区域的数据

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
    <title>Test</title>
</head>
<body>
<%
    request.setAttribute("str", "托马斯的小货车");
%>
<s:property value="#request.str"/>
</body>
</html>

# 号可以用来构建一个 Map

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
    <title>Test</title>
</head>
<body>
<%--构建 List--%>
<s:iterator var="letter" value="{'a','b','c'}">
    <s:property value="letter"/>|<s:property value="#letter"/>
</s:iterator>
<hr>
<%--构建 Map--%>
<s:iterator var="entry" value="#{1:'aa',2:'bb',3:'cc'}">
    <s:property value="key"/>|<s:property value="#entry.key"/>
    <s:property value="value"/>|<s:property value="#entry.value"/>
    <br>
</s:iterator>
</body>
</html>

% 号

% 号可以用来强制解析字符串为表达式

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
    <title>Test</title>
</head>
<body>
<%
    request.setAttribute("name", "托马斯");
%>

<s:property value="#request.name"/>
<br>
<%--
按如下嵌套标签会报错:
<s:textfield name="name" value="<s:property value="#request.name"/>" />
可以利用 %{} 强制解析表达式
--%>

<s:textfield name="name" value="%{#request.name}" />
</body>
</html>

image.png

$ 号

$ 号可以用来在配置文件中引用值栈中的值

<validators>
     <field name=”intb”>
             <field-validator type=”int”>
             <param name=”min”>10</param>
             <param name=”max”>100</param>
             < message>BAction-test校验:数字必须为${min}为${max}之间!</message>
         </field-validator>
     </field>
</validators>

Copyright: 采用 知识共享署名4.0 国际许可协议进行许可

Links: https://www.zze.xyz/archives/struts2-8.html

Buy me a cup of coffee ☕.