OGNL,全称为Object-Graph Navigation Language,它是一个功能强大的表达式语言,用来获取和设置Java对象的属性,它旨在提供一个更高的更抽象的层次来对Java对象图进行导航。
OGNL表达式的基本单位是"导航链",一般导航链由如下几个部分组成:
- 属性名称(property)
- 方法调用(method invoke)
- 数组元素
Struts2默认使用OGNL表达式进行数据的绑定。
页面取值:
名称 | servlet | ognl |
parameters | request.getParameter("username") | #username |
request | request.getAttribute("userName") | #request.userName |
session | session.getAttribute("userName") | #session.userName |
application | application.getAttribute("userName") | #application.userName |
attr | 用于按request > session > application顺序访问其属性(attribute) | #attr.userName相当于按顺序在以上三个范围(scope)内读取userName属性,直到找到为止 |
#符号的用途一般有三种。
1)访问非根对象属性,例如示例中的#session.msg表达式,由于Struts 2中值栈被视为根对象,所以访问其他非根对象时,需要加#前缀。实际上,#相当于 ActionContext.getContext();#session.msg表达式相当于ActionContext.getContext().getSession(). getAttribute(”msg”) 。
2)用于过滤和投影(projecting)集合,如示例中的persons.{?#this.age>20}。
3)用来构造Map,例如示例中的#{’foo1′:’bar1′, ’foo2′:’bar2′}。
创建一个web工程来简单试用一下:
struts.xml:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<constant name="struts.devMode" value="true" />
<!-- 通配符的使用 -->
<constant name="struts.enable.DynamicMethodInvocation" value="false" />
<constant name="struts.ognl.allowStaticMethodAccess" value="true"></constant>
<constant name="struts.i18n.encoding" value="GBK" />
<include file="com/smile/struts2/action/ognl.xml"></include>
</struts>
ognl.xml:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<!-- OGNL: Object Graph Navigation Language -->
<package name="user" extends="struts-default" namespace="/">
<action name="ognl" class="com.smile.struts2.action.OGNLAction">
<result>
/ognl.jsp
</result>
</action>
<action name="test" class="com.smile.struts2.action.TestAction">
<result type="chain">
ognl
</result>
</action>
</package>
</struts>
OGNLAction:
package com.smile.struts2.action;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.opensymphony.xwork2.ActionSupport;
import com.smile.struts2.bean.Cat;
import com.smile.struts2.bean.Dog;
import com.smile.struts2.bean.User;
public class OGNLAction extends ActionSupport{
private String username = "";
private String password = "";
private User user;
private Cat cat;
private List<User> users = new ArrayList<User>();
private Set<Dog> dogs = new HashSet<Dog>();
private Map<String,Dog> dogMap = new HashMap<String,Dog>();
public OGNLAction(){
users.add(new User(7));
users.add(new User(8));
users.add(new User(9));
dogs.add(new Dog("dog1"));
dogs.add(new Dog("dog2"));
dogs.add(new Dog("dog3"));
dogMap.put("dog101", new Dog("101"));
dogMap.put("dog102", new Dog("102"));
dogMap.put("dog103", new Dog("103"));
}
public List<User> getUsers() {
return users;
}
public void setUsers(List<User> users) {
this.users = users;
}
public Set<Dog> getDogs() {
return dogs;
}
public void setDogs(Set<Dog> dogs) {
this.dogs = dogs;
}
public Map<String, Dog> getDogMap() {
return dogMap;
}
public void setDogMap(Map<String, Dog> dogMap) {
this.dogMap = dogMap;
}
public Cat getCat() {
return cat;
}
public void setCat(Cat cat) {
this.cat = cat;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String execute(){
return SUCCESS;
}
public String m(){
return "Action m()";
}
}
我们在jsp界面里边可以这样访问:
<?xml version="1.0" encoding="GB18030" ?>
<%@ page language="java" contentType="text/html; charset=GB18030"
pageEncoding="GB18030"%>
<%@ taglib uri="/struts-tags" prefix="s" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GB18030" />
<title>OGNL表达式语言学习</title>
</head>
<body>
<ol>
<li>访问值栈中的action的普通属性: username = <s:property value="username"/> </li>
<li>访问值栈中对象的普通属性(get set方法):<s:property value="user.age"/> | <s:property value="user['age']"/> | <s:property value="user[\"age\"]"/> | wrong: <s:property value="user[age]"/></li>
<li>访问值栈中对象的普通属性(get set方法): <s:property value="cat.friend.name"/></li>
<li>访问值栈中对象的普通方法:<s:property value="password.length()"/></li>
<li>访问值栈中对象的普通方法:<s:property value="cat.miaomiao()" /></li>
<li>访问值栈中action的普通方法:<s:property value="m()" /></li>
<hr />
<li>struts2.1以后对已默认访问静态方法的设置为false 需要再struts.xml中添加设置才能访问静态方法 org.apache.struts2.default.properties : struts.ognl.allowStaticMethodAccess=false</li>
<li>访问静态方法:<s:property value="@com.smile.struts2.bean.S@s()"/></li>
<li>访问静态属性:<s:property value="@com.smile.struts2.bean.S@STR"/></li>
<li>访问Math类的静态方法:<s:property value="@@max(2,3)" /></li>
<hr />
<li>访问普通类的构造方法:<s:property value="new com.smile.struts2.bean.User(8)"/></li>
<hr />
<li>访问List:<s:property value="users"/></li>
<li>访问List中某个元素:<s:property value="users[1]"/></li>
<li>访问List中元素某个属性的集合:<s:property value="users.{age}"/></li>
<li>访问List中元素某个属性的集合中的特定值:<s:property value="users.{age}[0]"/> | <s:property value="users[0].age"/></li>
<li>访问Set:<s:property value="dogs"/></li>
<li>访问Set中某个元素:<s:property value="dogs[1]"/></li>
<li>访问Map:<s:property value="dogMap"/></li>
<li>访问Map中某个元素:<s:property value="dogMap.dog101"/> | <s:property value="dogMap['dog101']"/> | <s:property value="dogMap[\"dog101\"]"/></li>
<li>访问Map中所有的key:<s:property value="dogMap.keys"/></li>
<li>访问Map中所有的value:<s:property value="dogMap.values"/></li>
<li>访问容器的大小:<s:property value="dogMap.size()"/> | <s:property value="users.size"/> </li>
<hr />
<li>投影(过滤):<s:property value="users.{?#this.age==1}[0]"/></li>
<li>投影:<s:property value="users.{^#this.age>1}.{age}"/> ^字符表示开头 users.{^#this.age>1}.{age} 意思为age>1的开头的那个</li>
<li>投影:<s:property value="users.{$#this.age>1}.{age}"/> $字符表示结尾 users.{^#this.age>1}.{age} 意思为age>1的结尾的那个</li>
<li>投影:<s:property value="users.{$#this.age>1}.{age} == null"/></li>
<hr />
Value Stack中的通过数组来访问
<li>[]:<s:property value="[0].username"/></li>
<li>[]:<s:property value="[0].password"/></li>
<li>[]:<s:property value="[3]"/></li>
</ol>
<s:debug></s:debug>
</body>
</html>
我们需要创建的几个bean:
cat.java:
package com.smile.struts2.bean;
public class Cat {
public Cat(){
System.out.println("new Cat()");
}
private Dog friend;
public Dog getFriend() {
return friend;
}
public void setFriend(Dog friend) {
this.friend = friend;
}
public String miaomiao(){
return "I am a cat! miao~";
}
}
Dog.java:
package com.smile.struts2.bean;
public class Dog {
private String name;
public Dog(){
System.out.println("new Dog()");
}
public Dog(String name){
super();
this.name = name;
System.out.println("new Dog(String name)");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String toString(){
return "dog:"+name;
}
}
User.java:
package com.smile.struts2.bean;
public class User {
private int age;
public User(){
}
public User(int age){
super();
this.age = age;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String toString(){
return "user:"+age;
}
}
S.java:
package com.smile.struts2.bean;
public class S {
public S(){
}
public static String STR = "STATIC STRING";
public static String s(){
return "static method!";
}
}
运行结果如下图: