OGNL的全称为ObjectGraphic Navigation Language(对象图导航语言)。它是Struts2的默认表达式语言!
使用OGNL需要导入OGNL的Jar包:ognl-3.0.5.jar
1、EL一样的JavaBean导航;
2、调用对象方法;
3、调用类的静态方法;
4、索引数组元素;
5、操作集合;
1 取值
1.1 根中取
1.1.1根是javabean
1.1.2根是list([n]语法)
1.2 Map中取
2 赋值
2.1 表达式赋值
2.2 SetValue方法赋值
3 调用方法
4 调用静态方法
5 访问静态变量
6 数学运算符
7 “,”号连接
8 创建list
9 创建map
10 In与not in运算符
11 投影(了解)
12 过滤(了解)
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;
}
}
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 + "]";
}
}
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;
}
}
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([n]语法)
public void fun2() throws Exception{
//参数1: 填写ognl表达式
//参数2: Map => context 上下文
//参数3: javaBean / List / Map..... Root 根
//--------------------------------------------------------
List list = new ArrayList();
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();
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 list = new ArrayList();
//--------
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 list = new ArrayList();
//--------
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]]
}
}
描述: struts2为OGNL表达式准备了两个对象
ActionContext:
作为ognl表达式的Context
valueStack:
作为ognl表达式的Root
作用范围:值栈为request作用域中的一个属性,作用范围跟request一样,有多少个请求就有多少个值栈
以上两个对象的创建
都是strutsPrepareAndExecuteFilter中准备好.
ognl表达式:Ognl.getValue(ognl表达式,context,根);就是struts中搞的一个list模拟的栈结构,而值栈作为OGNL表达式的root,并且会把action对象放入值栈中。
requestScope、sessionscope、applicationScope三个域的数据都放入了attribute中,如果有重名的键 则会被覆盖:
最终 都是以requestScope中的为准
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";
}
}
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 + "]";
}
}
/index.jsp
/index.jsp
/index.jsp
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() ;
}
}
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.
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 {
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;
}
}
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]
表单提交,其中提交的键可以看作是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 {
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对象赋值了
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;
}
}
application/zip
is
attachment;filename="${fileName}"
10240
在xnl中使用ognl:${filename}:从根中找名为filename的属性
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;
}
}
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;
}
}
<%
request.setAttribute("name", "requestTom");
session.setAttribute("name", "sessionTom");
application.setAttribute("name", "applicationTom");
%>
#request.name:
#session.name:
#application.name:
name:
u.name:
#this[1].name:
/tag/demo2.jsp