struts2与OGNL表达式
2017-01-17 21:01
351 查看
OGNL表达式
一、什么是OGNl语言
OGNL的全称为ObjectGraphic Navigation Language(对象图导航语言)。它是Struts2的默认表达式语言!使用OGNL需要导入OGNL的Jar包:ognl-3.0.5.jar
强大的导航语言.一般我们使用ognl表达式取数据.
取数据的位置,需要给ognl准备两个.
context: 上下文=> 需要是一个map
root: 根 => 可以任何java对象=> javaBean,list,map,数组.....
规则: 表达式直接写标示从根下取
表达式以"#"开头表示从context中取
二、OGNL功能
1、EL一样的JavaBean导航;2、调用对象方法;
3、调用类的静态方法;
4、索引数组元素;
5、操作集合;
功能演示:
1 取值
1.1 根中取
1.1.1根是javabean
1.1.2根是list(
语法)
1.2 Map中取
2 赋值
2.1 表达式赋值
2.2 SetValue方法赋值
3 调用方法
4 调用静态方法
5 访问静态变量
6 数学运算符
7 “,”号连接
8 创建list
9 创建map
10 In与not in运算符
11 投影(了解)
12 过滤(了解)
Demo:
Address.java:
package cn.itheima.bean; public class Address { private String city; private String street; public String getCity() { return city; } public void setCity(String city) { this.city = city; } public String getStreet() { return street; } public void setStreet(String street) { this.street = street; } }
User.java:
package cn.itheima.bean; public class User { private String name; private String password; private int age ; private Address address; public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Address getAddress() { return address; } public void setAddress(Address address) { this.address = address; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } @Override public String toString() { return "User [name=" + name + ", password=" + password + ", address=" + address + "]"; } }
DateUtils.java:
package cn.itheima.utils; import java.text.SimpleDateFormat; import java.util.Date; public class DateUtils { public static double PI = 3.14159265357; public static String getTime(){ return new SimpleDateFormat("yyyy/MM/dd").format(new Date()); } public static String echo(String str){ return str; } }
Demo:
package cn.itheima.demo; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import ognl.Ognl; import org.junit.Test; import cn.itheima.bean.Address; import cn.itheima.bean.User; public class Demo { //1 演示ognl的基本使用 @Test //1.1.1 根是javabean public void fun1() throws Exception{ //参数1: 填写ognl表达式 //参数2: Map => context 上下文 //参数3: javaBean / List / Map..... Root 根 //-------------------------------------------------------- User u = new User(); u.setName("tom"); String name = (String) Ognl.getValue("name", new HashMap(), u); System.out.println(name); } @Test //1.1.2 根是list( 语法) public void fun2() throws Exception{ //参数1: 填写ognl表达式 //参数2: Map => context 上下文 //参数3: javaBean / List / Map..... Root 根 //-------------------------------------------------------- List<User> list = new ArrayList<User>(); User u1 = new User(); u1.setName("tom"); list.add(u1); //--------- User u2 = new User(); u2.setName("jerry"); list.add(u2); //ognl表达式 默认从根下取数据 String name = (String) Ognl.getValue("[0].name", new HashMap(), list); System.out.println(name); } @Test //1.2 Map中取 public void fun3() throws Exception{ Map< String, Object> context = new HashMap<String, Object>(); context.put("name", "tom"); //------------------------------- User u2 = new User(); u2.setName("jerry"); String name = (String) Ognl.getValue("name", context, u2);//从根中取 // String name = (String) Ognl.getValue("#name", context, u2);//从context中取 System.out.println(name); } @Test public void fun4() throws Exception{ User u = new User(); u.setName("jerry"); Address a = new Address(); a.setCity("北京"); u.setAddress(a); String city = (String) Ognl.getValue("address.city", new HashMap(), u); System.out.println(city); } @Test public void fun5() throws Exception{ //演示赋值1 User u = new User(); Ognl.getValue("name='tom'", new HashMap(), u); System.out.println(u.getName()); //tom } @Test public void fun6() throws Exception{ //演示赋值2 User u = new User(); Ognl.setValue("name", new HashMap(), u,"jerry"); System.out.println(u.getName()); //jerry } @Test public void fun7() throws Exception{ //演示方法调用(方法需要存在于根对象中) User u = new User(); Ognl.getValue("setName('jack')", new HashMap(), u); System.out.println(u.getName()); //jack } @Test public void fun8() throws Exception{ //演示静态方法调用(不受方法必须在根中的限制) User u = new User(); String time = (String) Ognl.getValue("@cn.itheima.utils.DateUtils@getTime()", new HashMap(), u); //使用@引用静态方法和静态变量 String echo = (String) Ognl.getValue("@cn.itheima.utils.DateUtils@echo('hiahia~~')", new HashMap(), u); System.out.println(time); //2015/06/27 System.out.println(echo); //hiahia~~ } @Test public void fun9() throws Exception{ //演示静态方法调用(不受方法必须在根中的限制) User u = new User(); double Pi= (Double) Ognl.getValue("@cn.itheima.utils.DateUtils@PI", new HashMap(), u); System.out.println(Pi); } @Test public void fun10() throws Exception{ //演示数学运算符 User u = new User(); int result= (Integer) Ognl.getValue("1+1", new HashMap(), u); System.out.println(result); } @Test public void fun11() throws Exception{ //演示","连接符 User u = new User(); String name = (String) Ognl.getValue("name='tom',name", new HashMap(), u); System.out.println(name); //tom } @Test public void fun12() throws Exception{ //演示 创建对象 (list) User u = new User(); List list = (List) Ognl.getValue("{'tom','jerry','jack','rose'}", new HashMap(), u); System.out.println(list); //[tom,jerry,jack,rose] } @Test public void fun13() throws Exception{ //演示 创建对象 (map) User u = new User(); Map map =(Map) Ognl.getValue("#{'name':'tom','age':'18'}", new HashMap(), u); System.out.println(map); //{name=tom,age=18} } @Test public void fun14() throws Exception{ //演示 创建对象 (user) User u = new User(); User u2 = (User) Ognl.getValue("new cn.itheima.bean.User()", new HashMap(), u); System.out.println(u2); //User [name=null,password=null,address=null] } @Test public void fun15() throws Exception{ //演示 in User u = new User(); boolean b = (Boolean) Ognl.getValue("'tom' in {'tom','jerry','jack','rose'}", new HashMap(), u); //判断tom是否在后面的集合中 boolean c = (Boolean) Ognl.getValue("'tom' not in {'tom','jerry','jack','rose'}", new HashMap(), u); System.out.println(b); //true System.out.println(c); //false } @Test public void fun16() throws Exception{ //集合的投影(了解) List<User> list = new ArrayList<User>(); //-------- User u1 = new User(); u1.setName("tom"); list.add(u1); //--------- User u2 = new User(); u2.setName("jerry"); list.add(u2); System.out.println(Ognl.getValue("#this.{name}", new HashMap(),list));//[tom,jerry] } @Test public void fun17() throws Exception{ //集合的选择(过滤) //集合的投影(了解) List<User> list = new ArrayList<User>(); //-------- User u1 = new User(); u1.setName("tom"); u1.setAge(10); list.add(u1); //--------- User u2 = new User(); u2.setName("jerry"); u2.setAge(20); list.add(u2); System.out.println(Ognl.getValue("#this.{?age > 18}", new HashMap(),list)); //[User [name=jerry,password=null,address=null]] } }
三、OGNL与struts2的结合
描述: struts2为OGNL表达式准备了两个对象ActionContext:
作为ognl表达式的Context
valueStack:
作为ognl表达式的Root
作用范围:值栈为request作用域中的一个属性,作用范围跟request一样,有多少个请求就有多少个值栈
以上两个对象的创建
都是strutsPrepareAndExecuteFilter中准备好.
ognl表达式:Ognl.getValue(ognl表达式,context,根);
1、值栈(作为ognl表达式的根)
就是struts中搞的一个list模拟的栈结构,而值栈作为OGNL表达式的root,并且会把action对象放入值栈中。requestScope、sessionscope、applicationScope三个域的数据都放入了attribute中,如果有重名的键 则会被覆盖:
最终 都是以requestScope中的为准
2、ActionContext(struts2数据中心)
Demo:
action:
package cn.itheima.c_vs; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionSupport; import com.opensymphony.xwork2.util.ValueStack; public class Demo1Action extends ActionSupport { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } public String execute(){ System.out.println("action中的name属性值:"+name); //获得值栈 ValueStack vs =ActionContext.getContext().getValueStack(); //获得栈顶的User对象 User u =(User) vs.getRoot().peek(); //打印user对象的name属性 System.out.println("现在在栈顶的User对象的Name属性:"+u.getName()); return "success"; } }
User:
package cn.itheima.c_vs; public class User { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "User [name=" + name + "]"; } }
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> <package name="vs" namespace="/vs" extends="struts-default" > <interceptors> <interceptor name="vs" class="cn.itheima.c_vs.VSInterceptor"></interceptor> </interceptors> <action name="Demo1Action" class="cn.itheima.c_vs.Demo1Action" > <result name="success" type="dispatcher" >/index.jsp</result> <interceptor-ref name="vs"></interceptor-ref> <interceptor-ref name="defaultStack"></interceptor-ref> </action> <action name="Demo2Action" class="cn.itheima.c_vs.Demo2Action" > <result name="success" type="dispatcher" >/index.jsp</result> </action> <action name="Demo3Action" class="cn.itheima.c_vs.Demo3Action" > <result name="success" type="dispatcher" >/index.jsp</result> </action> </package> </struts>
VSInterceptor:
package cn.itheima.c_vs; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.interceptor.AbstractInterceptor; import com.opensymphony.xwork2.util.ValueStack; public class VSInterceptor extends AbstractInterceptor { @Override public String intercept(ActionInvocation invocation) throws Exception { //1 得到ActionContext数据中心 ActionContext ac = ActionContext.getContext(); //2 获得 ValueStack(List) ValueStack vs = ac.getValueStack(); //3 取出栈中的第一个对象验证是否是Action Object obj = vs.getRoot().peek(); System.out.println("栈顶的对象是:"+obj);//应该是我们写Demo1Action //4 创建一个User对象 压入栈中 User u = new User(); vs.getRoot().push(u);//哈哈,现在User对象替代Action在栈顶了!! //放行 return invocation.invoke() ; } }
Demo2Action:
package cn.itheima.c_vs; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionSupport; import com.opensymphony.xwork2.util.ValueStack; public class Demo2Action extends ActionSupport { private User user; public String execute(){ // http://liuyd:8080/struts2-demo3/vs/Demo2Action.do?user.name=tom System.out.println(user); return "success"; } public User getUser() { return user; } public void setUser(User user) { this.user = user; } }
结合演示:
1. <s:debug>标签介绍
package cn.itheima.c_vs; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionSupport; import com.opensymphony.xwork2.ModelDriven; import com.opensymphony.xwork2.util.ValueStack; public class Demo3Action extends ActionSupport implements ModelDriven<User> { private User user = new User(); public String execute(){ // http://liuyd:8080/struts2-demo3/vs/Demo2Action.do?name=tom System.out.println(user); return "success"; } public User getUser() { return user; } public void setUser(User user) { this.user = user; } //--------------------------------------------------- public User getModel() { return user; } }
2. 将表单的参数赋值到对象中(表达式方式)
超链提交参数:?user.name=tom 把参数直接赋值到了user对象中
user.name键作为ognl表达式访问root中的属性
action:
package cn.itheima.c_vs; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionSupport; import com.opensymphony.xwork2.util.ValueStack; public class Demo2Action extends ActionSupport { private User user; public String execute(){ // http://liuyd:8080/struts2-demo3/vs/Demo2Action.do?user.name=tom System.out.println(user); return "success"; } public User getUser() { return user; } public void setUser(User user) { this.user = user; } }
user:
package cn.itheima.c_vs; public class User { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "User [name=" + name + "]"; } }控制台打印:User [name=tom]
3. 将表单的参数赋值到对象中(ModelDriver方式)
表单提交,其中提交的键可以看作是ognl表达式Action中有User对象,我们想直接将表单参数提交到User对象中封装,做法:
1>提交的参数的键=> user.name 就会在值栈中查找名为user的对象,并赋值到该对象的name属性
2>使用ModelDriven,我们的Action在getModel方法中将User对象返回.ModelDriven拦截器会将我们返回的User对象放入值栈中(栈顶),那么 在表单中直接提交name,将会把name值装入栈顶的user对象的name属性
访问的方式使用:?name=tom 正常是从栈顶的action中找 找不到
思路:把user对象放到栈顶,这样name=tom就可以直接给user对象赋值了
步骤:实现ModelDriven接口,实现getModel方法,在该方法中返回一个对象,该对象就是想要赋值到的那个对象(user)
action:
package cn.itheima.c_vs; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionSupport; import com.opensymphony.xwork2.ModelDriven; import com.opensymphony.xwork2.util.ValueStack; public class Demo3Action extends ActionSupport implements ModelDriven<User> { private User user = new User(); public String execute(){ // http://liuyd:8080/struts2-demo3/vs/Demo2Action.do?name=tom System.out.println(user); return "success"; } public User getUser() { return user; } public void setUser(User user) { this.user = user; } //--------------------------------------------------- public User getModel() { return user; } }底层是用modelDriven拦截器实现的,该拦截器位于在params拦截器之前
modelDriven拦截器会把返回的那个对象压入栈顶,这样赋值的时候就是给user对象赋值了
4. 文件下载中文件名乱码问题解决(配置文件中使用OGNL)
action:package cn.itheima.b_ognl; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import javax.servlet.ServletContext; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionSupport; public class Demo1Action extends ActionSupport { private InputStream is ; public InputStream getIs() { //1 获得ServletContext ServletContext sc = ServletActionContext.getServletContext(); //2 获得apache-tomcat-6.0.35.zip的流 is = sc.getResourceAsStream("/WEB-INF/apache-tomcat-6.0.35.zip"); //3 返回 return is; } public String getFileName() { try { return URLEncoder.encode("汤姆凯特6.zip","UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); return null; } } @Override public String execute() throws Exception { return SUCCESS; } }
struts.xml:
<package name="ognl" namespace="/ognl" extends="struts-default" > <action name="Demo1Action" class="cn.itheima.b_ognl.Demo1Action"> <result name="success" type="stream" > <param name="contentType">application/zip</param> <param name="inputName">is</param> <!-- 1.相应头中只能使用latin(Iso-8859-1)码表 2.使用URLEncode编码,对中文进行编码才能发送 => %E6%F7 3. 在struts.xml配置文件中可以使用ognl表达式=> ${} 在扩种书写ognl(注意:虽然跟el表达式格式看似相同,但是就是ognl不是el.) --> <param name="contentDisposition">attachment;filename="${fileName}"</param> <!-- 从action中去找名为fileName的属性 --> <param name="bufferSize">10240</param> </result> </action>在xnl中使用ognl:${filename}:从根中找名为filename的属性
因为根中是struts的值栈,值栈中装了action,所以最终从action中找名为filename的属性
所以在action中提供filename属性,提供get方法
5. Struts2标签中OGNL表达式(<s:properties>)
<s:debug>标签:两部分:值栈(Value Stack Contents)和数据中心(Stack Context)
在jsp中使用标签,要导库:<%@ taglib prefix="s" uri="/struts-tags" %>
user:
package cn.itheima.b_ognl; public class User { private String name; private String password; public User() { } public User(String name, String password) { super(); this.name = name; this.password = password; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
action:
package cn.itheima.b_ognl; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import javax.servlet.ServletContext; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionSupport; public class Demo2Action extends ActionSupport { private String name = "ActionTom"; private User u = new User("beanTom","1234"); public User getU() { return u; } public void setU(User u) { this.u = u; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String execute() throws Exception { //将User对象压入值栈中, 栈顶是User对象 ActionContext.getContext().getValueStack().push(u); return SUCCESS; } }
jsp:
<body> <% request.setAttribute("name", "requestTom"); session.setAttribute("name", "sessionTom"); application.setAttribute("name", "applicationTom"); %> <!-- <s:property/> 标签中使用ognl表达式 --> <!-- 使用ognl表达式分别取得request session application 中的属性 ActionContext.getContext().get("request").get("name") --> #request.name:<s:property value="#request.name" /><br> #session.name:<s:property value="#session.name" /><br> #application.name:<s:property value="#application.name" /><br> name:<s:property value="name" /> <hr> <!-- 访问Action中user对象的name属性 --> u.name:<s:property value="u.name" /> <hr> <!-- 栈顶是User对象,Action在User对象下面 --> #this[1].name:<s:property value="#this[1].name" /> <!--从值栈中取出脚标为1的对象--> <s:debug></s:debug> </body>
xml:
<action name="Demo2Action" class="cn.itheima.c_tag.Demo2Action"> <result name="success" >/tag/demo2.jsp</result> </action>
相关文章推荐
- Struts2深入学习----OGNL表达式原理
- OGNL表达式struts2标签“%,#,$”
- Struts2标签、Ognl表达式、el表达式、jstl标签库这四者之间的关系与各自使用
- Struts2 OGNL表达式语言
- Struts2中的技术分析之OGNL表达式概述(了解)
- Struts2使用OGNL表达式封装输入数据(直接封装Map类型)
- struts2 OGNL表达式
- Struts2总结---OGNL表达式的基本语法和用法 (8)
- Struts2 使用OGNL表达式访问ENUM对象
- OGNL表达式struts2标签“%,#,$”
- Struts2学习记录-Value Stack(值栈)和OGNL表达式
- Struts2-03-OGNL表达式
- OGNL表达式struts2标签“%,#,$”
- Struts中的OGNL表达式语言1/Struts标签与OGNL表达式语言实例演练2/Struts2常用标签总结3
- [转载]OGNL表达式struts2标签“%,#,$”
- JAVAEE学习——struts2_03:OGNL表达式、OGNL与Struts2的结合和练习:客户列表
- Struts2系统学习(16)OGNL表达式及基本原理分析
- struts2 OGNL 表达式
- JavaWeb--Struts2——OGNL表达式
- struts2中使用ognl表达式时各种符号的使用规则$,#,%