OGNL表达式是什么
OGNL(Object-Graph Navigation Language对象图导航语言),是一种功能强大的表达式语言,通过它简单一致的表达式语法,可以存取对象的任意属性,调用对象的方法,遍历整个对象的结构图,实现字段类型转化等功能。
一、表达式:
表达式(Expression)是整个OGNL的核心内容,所有的OGNL操作都是针对表达式解析后进行的。通过表达式来告诉OGNL操作到底要干些什么。因此,表达式其实是一个带有语法含义的字符串,整个字符串将规定操作的类型和内容。OGNL表达式支持大量的表达式,如“链式访问对象”、表达式计算、甚至还支持Lambda表达式。
二、Root对象:
OGNL的Root对象可以理解为OGNL的操作对象。当我们指定了一个表达式的时候,我们需要指定这个表达式针对的是哪个具体的对象。而这个具体的对象就是Root对象,这就意味着,如果有一个OGNL表达式,那么我们需要针对Root对象来进行OGNL表达式的计算并且返回结果。
三、上下文环境
有个Root对象和表达式,我们就可以使用OGNL进行简单的操作了,如对Root对象的赋值与取值操作。但是,实际上在OGNL的内部,所有的操作都会在一个特定的数据环境中运行。这个数据环境就是上下文环境(Context)。OGNL的上下文环境是一个Map结构,称之为OgnlContext。Root对象也会被添加到上下文环境当中去。
OGNL是 Struts 2的默认表达式语言。要结合Struts 2的标志一起使用。主要是#、%和$这三个符号的使用[email protected]
#符号用法
1、访问非根对象(struts中值栈为根对象)
例如#session.msg表达式,由于Struts 2中值栈被视为根对象,所以访问其他非根对象时,需要加#前缀。实际上,#相当于ActionContext. getContext();#session.msg表达式相当于ActionContext.getContext().getSession(). getAttribute(“msg”) 。OGNL获取值栈中的对象是不需要加#的。
OGNL中的#号可以取出上下文中存放的对象
名称 | 用途 | 例子 |
parameters | 包含当前HTTP请求参数的Map | #parameters.id[0]相当于request.getParameter(“id”) |
request | 包含当前HttpServletRequest的属性的Map | #request.userName相当于request.getAttribute(“userName”) |
session | 包含当前HttpSession的属性的Map | #session.userName相当于session.getAttribute(“userName”) |
application | 包含当前应用的ServletContext的属性的Map | #application.userName相当于application.getAttribute(“userName”) |
attr | 用于按request>>session>>application顺序访问其属性 | #attr.userName相当于按顺序从request、session、application三个范围读取userName属性直到找到为止 |
2、用于过滤和投影(projecting)集合
#this代表当前元素,问号?是把所有满足条件的元素都取出来;上箭头^是开始的意思,即取符合条件的数据索引中第一条数据;$是结束的意思,即取符合条件的数据索引中最后一条数据。这三个符号:问号、上箭头、美元符所返回的都是List
3、用来构造Map
例如示例中的#{‘foo1′:’bar1’, ‘foo2′:’bar2’}。
“%”符号的用途
是在标签的属性被理解为字符串类型时,告诉执行环境%{}里的是OGNL表达式
<s:url value=”test.jsp?age=#userlist[‘admin’]”>→test.jsp?#userlist[‘admin’]—可见当字符串与OGNL表达式串起来时,只会被当作字符串对待,并不执行
<s:url value=”test.jsp?age=%{#userlist[‘admin’]}”>→test.jsp?age=44—使用了该符号,就可以使得OGNL表达式被执行
1、使用%{}可以取出保存在值堆栈中的Action对象,直接调用它的方法
2、如果Action继承了ActionSupport,那么在页面标签中可以使用%{getText(‘key’)}获取国际化信息
“$”号的用途
top语法
N语法
新的集合。语法为collection.{XXX},XXX就是集合中每个元素的公共属性。
新的集合。语法为collection.{Y XXX},其中Y是一个选择操作符,XXX是选择用的逻辑表达式
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" > <web-app> <display-name>Archetype Created Web Application</display-name> <filter> <filter-name>struts2</filter-name> <filter-class> org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter </filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>struts2</groupId> <artifactId>struts2</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>war</packaging> <name>struts2</name> <description/> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>javax</groupId> <artifactId>javaee-api</artifactId> <version>7.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.glassfish.web</groupId> <artifactId>javax.servlet.jsp.jstl</artifactId> <version>1.2.2</version> </dependency> <dependency> <groupId>org.apache.struts</groupId> <artifactId>struts2-core</artifactId> <version>2.3.16</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-io</artifactId> <version>1.3.2</version> </dependency> </dependencies> <build> <sourceDirectory>src</sourceDirectory> <resources> <resource> <directory>src</directory> <excludes> <exclude>**/*.java</exclude> </excludes> </resource> </resources> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>2.3.2</version> <configuration> <source>1.7</source> <target>1.7</target> </configuration> </plugin> <plugin> <artifactId>maven-war-plugin</artifactId> <version>2.2</version> <configuration> <warSourceDirectory>${basedir}/WebRoot</warSourceDirectory> <version>3.1</version> <failOnMissingWebXml>false</failOnMissingWebXml> </configuration> </plugin> </plugins> </build> </project>
<?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.enable.DynamicMethodInvocation" value="true"></constant> <!-- 开启开发者模式 --> <constant name="struts.devMode" value="true"></constant> <!-- 开启OGNL静态方调用 --> <constant name="struts.ognl.allowStaticMethodAccess" value="true"></constant> <package name="cn.test.action" namespace="/" extends="struts-default" > <action name="HelloWorldAction" class="cn.test.OgnlAction" method="execute"> <result name="success">/WEB-INF/page/index.jsp</result> </action> </package> </struts>
<?xml version="1.0" encoding="UTF-8"?> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ 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=UTF-8" /> <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>访问静态方法:<s:property value="@[email protected]()"/></li> <li>访问静态属性:<s:property value="@[email protected]"/></li> <li>访问Math类的静态方法:<s:property value="@@max(2,3)" /></li> <hr /> <li>访问普通类的构造方法:<s:property value="new cn.test.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> <!-- 这样 是不能显示任何信息的。 因为 set是 无序。不能像 list那样 list[1] map[key] 那样 直接访问 --> <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 /> <!-- users中 age等于1的user中的第一个user --> <li>投影(过滤):<s:property value="users.{?#this.age>1}[0]"/></li> <!-- users中 age大于1的user中的第一个user --> <li>投影:<s:property value="users.{^#this.age>1}.{age}"/></li> <!-- users中 age大于1的user中的最后一个user --> <li>投影:<s:property value="users.{$#this.age>1}.{age}"/></li> <li>投影:<s:property value="users.{$#this.age>1}.{age} == null"/></li> <hr /> <li>[]:<s:property value="[1].dogMap.dog101"/></li> </ol> <s:debug></s:debug> </body> </html>
Action类
package cn.test; 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.ActionContext; import com.opensymphony.xwork2.ActionSupport; public class OgnlAction extends ActionSupport { private Cat cat=new Cat(); private Map<String, Dog> dogMap = new HashMap<String, Dog>(); private Set<Dog> dogs = new HashSet<Dog>(); private String username="11"; private String password="22"; private User user=new User(); private List<User> users = new ArrayList<User>(); public OgnlAction() { users.add(new User(1,"11")); users.add(new User(2,"22")); users.add(new User(3,"33")); dogs.add(new Dog("dog1")); dogs.add(new Dog("dog2")); dogs.add(new Dog("dog3")); dogMap.put("dog100", new Dog("dog100")); dogMap.put("dog101", new Dog("dog101")); dogMap.put("dog102", new Dog("dog102")); ActionContext.getContext().getValueStack(); } public String execute() { return SUCCESS; } public String m() { return "hello"; } 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 Cat getCat() { return cat; } public void setCat(Cat cat) { this.cat = cat; } public Map<String, Dog> getDogMap() { return dogMap; } public void setDogMap(Map<String, Dog> dogMap) { this.dogMap = dogMap; } public Set<Dog> getDogs() { return dogs; } public void setDogs(Set<Dog> dogs) { this.dogs = dogs; } public List<User> getUsers() { return users; } public void setUsers(List<User> users) { this.users = users; } }
Cat类
package cn.test; public class Cat { private Dog friend; public Dog getFriend() { return friend; } public void setFriend(Dog friend) { this.friend = friend; } public String miaomiao() { return "miaomiao"; } }
Dog类
package cn.test; public class Dog { private String name; public Dog() { } public Dog(String name) { super(); this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "dog: " + name; } }
User类
package cn.test; public class User { private int age = 8; private String username; public User() { System.out.println(age); } public User(int age,String username) { super(); this.age = age; this.username=username; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } @Override public String toString() { return "user" + age; } }
S类
package cn.test; public class S { public static String STR = "STATIC STRING"; public static String s() { return "static method"; } }
测试结果:
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/11189.html