欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Java EE SSH框架之Struts2 (5)—— Struts2与OGNL表达式的结合

程序员文章站 2022-06-02 14:30:55
...

一、OGNL表达式

1.1、OGNL表达式简单介绍

OGNL:对象视图导航

不仅仅可以视图导航,支持比EL表达式更加丰富的功能。

使用OGNL表达式之前要先导包

Java EE SSH框架之Struts2 (5)—— Struts2与OGNL表达式的结合

了解下OGNL表达式取值范围:

Java EE SSH框架之Struts2 (5)—— Struts2与OGNL表达式的结合


1.2、OGNL表达式语法

参考下例:

User.java

package com.zl.beans;

public class User {
	private String name;
	private Integer age;
	
	public User() {
		super();
		// TODO Auto-generated constructor stub
	}
	public User(String name, Integer age) {
		super();
		this.name = name;
		this.age = age;
	}
	
	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;
	}
}

HuiYing.java

package com.zl.staticsDemo;

public class HuiYing {
    //专门用于测试,传什么参数返回什么参数
	public static Object echo(Object o) {
		return o;
	}
}

Demo1.java

package com.zl.grammer;

import java.util.HashMap;
import java.util.Map;

import org.junit.Test;

import com.zl.beans.User;

import ognl.Ognl;
import ognl.OgnlContext;
import ognl.OgnlException;
//基本OGNL语法
public class Demo1 {
    @Test
	public void fun1() throws OgnlException {
    //准备OGNLContext
    	//准备Root
    	User rootUser = new User("Tom",18);
    	//准备Context
    	Map<String,User> context = new HashMap<String,User>();
    	context.put("user1", new User("Jack",18));
    	context.put("user2", new User("Rose",20));
    	OgnlContext oc = new OgnlContext();
    	oc.setRoot(rootUser);//将rootUser作为root部分
    	oc.setValues(context);//将context这个Map作为Context部分
    	
    	//书写OGNL
    	//取值
    	//1.1取出root中User对象的name属性、age属性
    	String name = (String)Ognl.getValue("name", oc, oc.getRoot());
    	Integer age = (Integer)Ognl.getValue("age", oc, oc.getRoot());
    	System.out.println("root中User的name、age:"+name+"\t"+age);   	
    	//1.2取出context中User对象的name、age属性
    	String name1 = (String) Ognl.getValue("#user1.name", oc, oc.getRoot());
    	Integer age1 = (Integer) Ognl.getValue("#user1.age", oc, oc.getRoot());
    	System.out.println("Context中两个User的name、age:"+name1+"\t"+age1+"\n");

    	//赋值
    	//2.1给root中的user对象属性name重新赋值
    	String name2 = (String)Ognl.getValue("name='汤姆'", oc,oc.getRoot());
    	//2.2给context中的user1对象的属性name重新赋值
    	String name3 = (String) Ognl.getValue("#user1.name='杰克'", oc, oc.getRoot());
    	System.out.println("root、context里重新赋值后的name值分别为:"+name2+"\t"+name3+"\n");
    	
    	//3.调用方法
    	//3.1调用root中的方法,setName()、getName()
    	Ognl.getValue("setName('李磊')", oc,oc.getRoot());
    	String name4 = (String) Ognl.getValue("getName()", oc, oc.getRoot());
    	//3.2调用Context中的方法setName()、getName()
    	Ognl.getValue("#user1.setName('Lucky')", oc,oc.getRoot());
    	String name5 = (String) Ognl.getValue("#user1.getName()", oc,oc.getRoot());
    	System.out.println("分别调用root中user和Context中user1的setName方法后的name值分别为:"+name4+"\t"+name5+"\n");
    	
    	//3.3调用静态方法
    	String str = (String)Ognl.getValue("@aaa@qq.com('hello 侬好!')",oc,oc.getRoot());
    	System.out.println("调用静态方法"+str);
    	
    	//3.4访问静态属性PI(double)
    	//double pi = (double)Ognl.getValue("@aaa@qq.com",oc,oc.getRoot());
    	double pi = (double)Ognl.getValue("@@PI",oc,oc.getRoot());
    	System.out.println(pi);
    	System.out.println();
    	
    	//4、创建对象
    	//4.1创建List对象
    	Integer size = (Integer)Ognl.getValue("{'blue','red','pink'}.size", oc,oc.getRoot());
    	String color = (String)Ognl.getValue("{'blue','red','pink'}[0]", oc,oc.getRoot());
    	String color2 = (String)Ognl.getValue("{'blue','red','pink'}.get(2)", oc,oc.getRoot());
    	System.out.println("list的长度:"+size+",list第1个元素:"+color+",List第3个元素:"+color2);
    	//4.2创建Map对象
    	Integer size1 = (Integer)Ognl.getValue("#{'sky':'blue','blood':'red','face':'pink'}.size", oc,oc.getRoot());
    	String sky = (String)Ognl.getValue("#{'sky':'blue','blood':'red','face':'pink'}['sky']", oc,oc.getRoot());
    	String blood = (String)Ognl.getValue("#{'sky':'blue','blood':'red','face':'pink'}.get('blood')", oc,oc.getRoot());
    	System.out.println("map的长度:"+size1+",map中键为sky的值:"+sky+",map中键为blood的值:"+blood);

    }
} 
Run As ->Junit Test, 运行结果:

Java EE SSH框架之Struts2 (5)—— Struts2与OGNL表达式的结合


二、Struts2 与OGNL的结合

2.1、Struts2与OGNL结合原理

    OGNL表达式想要运行,需要准备一个OGNLContext,Struts2就准备了一个OGNLContext,名叫ValueStack。ValueStack由两部分构成。一部分叫做Root,放置的是一个栈。一部分叫做Context,是将我们之前学过的ActionContext(数据中心)放入。

补充:是先进后出,有push压栈方法、pop弹栈方法


ValueStack是一个接口,OgnlValueStack为其实现类

 OgnlValueStack中定义了两个属性:

    CompoundRoot root;——栈(CompoundRoot类中定义了push和pop方法)

    transient Map<String,Object> context; ——数据中心


默认情况下,stack(栈)中放置当前访问的Action对象!ActionContext(数据中心)中放置的是request、response、ServletContext、requestScope、sessionScope、applicationScope、params和attrs!


2.2、参数赋值

Java EE SSH框架之Struts2 (5)—— Struts2与OGNL表达式的结合


Java EE SSH框架之Struts2 (5)—— Struts2与OGNL表达式的结合


Java EE SSH框架之Struts2 (5)—— Struts2与OGNL表达式的结合

模型驱动中,

将对象user压入栈顶:

1.获得值栈

ValueStack vs = ActionContext.getContext().getValueStack();

2.将user压入栈顶

vs.push(user);

    将上述语句加到prepare()方法中,该Action要实现Preparable接口,prepare()为Preparable接口的方法,保证该方法可以在params拦截器给user对象的name属性赋值之前执行。


上述方法过于繁琐,需要非常了解Struts2,下面这钟方式更推荐使用:

实现ModelDriven<User>接口(<User>泛型,这里只是举例),重写getModel()方法,直接return user;


相关标签: OGNL