1. OGNL表达式
1.1 什么是OGNL表达式
OGNL:对象视图导航语言
使用OGNL表达式,需要两个前提
- 需要一个Root,这里用一个User对象来做Root
- 需要一个context(Map)
User对象
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;
}
@Override
public String toString() {
return "User [name=" + name + ", age=" + age + "]";
}
}
准别一个回音方法
public class echoUtils {
//回音方法
public static Object echo(Object o){
return o;
}
}
//展示OGNL语法
public class Demo {
@Test
//准备工作
public void fun1() throws Exception{
//准备ONGLContext
//准备Root
User rootUser = new User("tom",18);
//准备Context
Map context = new HashMap();
context.put("user1", new User("jack",18));
context.put("user2", new User("rose",22));
OgnlContext oc = new OgnlContext();
//将rootUser作为root部分
oc.setRoot(rootUser);
//将context这个Map作为Context部分
oc.setValues(context);
//书写OGNL
Ognl.getValue("", oc, oc.getRoot());
}
@Test
//基本语法演示
//取出root中的属性值
public void fun2() throws Exception{
//准备ONGLContext
//准备Root
User rootUser = new User("tom",18);
//准备Context
Map context = new HashMap();
context.put("user1", new User("jack",18));
context.put("user2", new User("rose",22));
OgnlContext oc = new OgnlContext();
oc.setRoot(rootUser);
oc.setValues(context);
//书写OGNL
//取出root中user对象的name属性
String name = (String) Ognl.getValue("name", oc, oc.getRoot());
Integer age = (Integer) Ognl.getValue("age", oc, oc.getRoot());
System.out.println(name);
System.out.println(age);
}
@Test
//基本语法演示
//取出context中的属性值
public void fun3() throws Exception{
//准备ONGLContext
//准备Root
User rootUser = new User("tom",18);
//准备Context
Map context = new HashMap();
context.put("user1", new User("jack",18));
context.put("user2", new User("rose",22));
OgnlContext oc = new OgnlContext();
oc.setRoot(rootUser);
oc.setValues(context);
//书写OGNL
//取出context中键为user1对象的name属性
String name = (String) Ognl.getValue("#user1.name", oc, oc.getRoot());
String name2 = (String) Ognl.getValue("#user2.name", oc, oc.getRoot());
Integer age = (Integer) Ognl.getValue("#user2.age", oc, oc.getRoot());
System.out.println(name);
System.out.println(name2);
System.out.println(age);
}
@Test
//基本语法演示
//为属性赋值
public void fun4() throws Exception{
//准备ONGLContext
//准备Root
User rootUser = new User("tom",18);
//准备Context
Map context = new HashMap();
context.put("user1", new User("jack",18));
context.put("user2", new User("rose",22));
OgnlContext oc = new OgnlContext();
oc.setRoot(rootUser);
oc.setValues(context);
//书写OGNL
//将root中的user对象的name属性赋值
Ognl.getValue("name='jerry'", oc, oc.getRoot());
String name = (String) Ognl.getValue("name", oc, oc.getRoot());
String name2 = (String) Ognl.getValue("#user1.name='冬冬',#user1.name", oc, oc.getRoot());
System.out.println(name);
System.out.println(name2);
}
@Test
//基本语法演示
//调用方法
public void fun5() throws Exception{
//准备ONGLContext
//准备Root
User rootUser = new User("tom",18);
//准备Context
Map context = new HashMap();
context.put("user1", new User("jack",18));
context.put("user2", new User("rose",22));
OgnlContext oc = new OgnlContext();
oc.setRoot(rootUser);
oc.setValues(context);
//书写OGNL
//调用root中user对象的setName方法
Ognl.getValue("setName('lilei')", oc, oc.getRoot());
String name = (String) Ognl.getValue("getName()", oc, oc.getRoot());
String name2 = (String) Ognl.getValue("#user1.setName('lucy'),#user1.getName()", oc, oc.getRoot());
System.out.println(name);
System.out.println(name2);
}
@Test
//基本语法演示
//调用静态方法
public void fun6() throws Exception{
//准备ONGLContext
//准备Root
User rootUser = new User("tom",18);
//准备Context
Map context = new HashMap();
context.put("user1", new User("jack",18));
context.put("user2", new User("rose",22));
OgnlContext oc = new OgnlContext();
oc.setRoot(rootUser);
oc.setValues(context);
//书写OGNL
String name = (String) Ognl.getValue("@a_ognl.EchoUtils@echo('hello 冬冬!')", oc, oc.getRoot());
//Double pi = (Double) Ognl.getValue("@java.lang.Math@PI", oc, oc.getRoot());
Double pi = (Double) Ognl.getValue("@@PI", oc, oc.getRoot());
System.out.println(name);
System.out.println(pi);
}
@Test
//基本语法演示
//ognl创建对象-list|map
public void fun7() throws Exception{
//准备ONGLContext
//准备Root
User rootUser = new User("tom",18);
//准备Context
Map context = new HashMap();
context.put("user1", new User("jack",18));
context.put("user2", new User("rose",22));
OgnlContext oc = new OgnlContext();
oc.setRoot(rootUser);
oc.setValues(context);
//书写OGNL
//创建list对象
Integer size = (Integer) Ognl.getValue("{'tom','jerry','jack','rose'}.size()", oc, oc.getRoot());
String name = (String) Ognl.getValue("{'tom','jerry','jack','rose'}[0]", oc, oc.getRoot());
String name2 = (String) Ognl.getValue("{'tom','jerry','jack','rose'}.get(1)", oc, oc.getRoot());
/*System.out.println(size);
System.out.println(name);
System.out.println(name2);*/
//创建Map对象
Integer size2 = (Integer) Ognl.getValue("#{'name':'tom','age':18}.size()", oc, oc.getRoot());
String name3 = (String) Ognl.getValue("#{'name':'tom','age':18}['name']", oc, oc.getRoot());
Integer age = (Integer) Ognl.getValue("#{'name':'tom','age':18}.get('age')", oc, oc.getRoot());
System.out.println(size2);
System.out.println(name3);
System.out.println(age);
}
}
2. ognl表达式与Struts2框架结合原理
2.1 Struts2使用ognl
- 需要一个Root,将Action对象放入,当获取从jsp中提交的表单参数的时候,是将user对象压栈,这样user在栈顶,ognl表达式默认会操作栈顶对象
- 需要一个context(Map),将valueStack放入
2.2 栈
栈的特性
先进后出栈必须具备的两个方法
这里栈是由ArrayList模拟的
public Object pop() {
return this.remove(0);
}
public void push(Object o) {
this.add(0, o);
}
2.3 参数赋值原理
form.jsp
Insert title here
public class Demo2Action extends ActionSupport implements ModelDriven {
private User u = new User();
@Override
public String execute() throws Exception {
System.out.println(u);
return SUCCESS;
}
// Preparable接口的方法,用来提前将user对象压栈
/*@Override
public void prepare() throws Exception {
//压入栈顶
//1获得值栈
ValueStack vs = ActionContext.getContext().getValueStack();
//2将u压入栈顶
vs.push(u);
}*/
@Override
public User getModel() {
return u;
}
}
Struts2中的filter执行顺序,modelDriven和prepare的作用是一样的,只是不需要自己压栈了,只需要返回user对象
input,back,cancel,browse
input,back,cancel,browse
2.4 配置文件中使用ognl表达式
Demo1Action
/
${name}
public class Demo3Action extends ActionSupport {
private String name;
@Override
public String execute() throws Exception {
name = "jerry";//从数据库中查询
return SUCCESS;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
3. jsp页面使用ognl表达式
- 客户列表的Action使用ActionContext进行参数获取和参数放置
public String list() throws Exception {
ActionContext.getContext().getValueStack();
// 1. 接受参数
// String cust_name = ServletActionContext.getRequest().getParameter("cust_name");
String cust_name = (String) ActionContext.getContext().getParameters().get("cust_name");
// 2. 创建离线查询对象
DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Customer.class);
// 3. 根据参数封装查询条件
if (StringUtils.isNotBlank(cust_name)) {
detachedCriteria.add(Restrictions.like("cust_name", "%" + cust_name + "%"));
}
List list = customerService.getAll(detachedCriteria);
// ServletActionContext.getRequest().setAttribute("list", list);
ActionContext.getContext().put("list", list);
return "list";
}
- jsp页面使用ognl来获取服务器发送的数据
引入标签库
<%@ taglib prefix="s" uri="/struts-tags" %>
方式一:
修改
删除
方式二:
修改
删除