概述
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>
$ 号
$ 号可以用来在配置文件中引用值栈中的值
<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>
评论区