OGNL概述
- OGNL同EL表达式类似,但又比JSTL功能强大且高效。
- 主要在struts2里操作值栈数据
- 一般把ognl表达式和struts2标签结合起来使用
- ognl不是struts2的一部分,只不过经常和struts2搭配起来使用
- jar包
如何使用ognl表达式和struts2标签
- ognl的使用
- 在jsp页面中引入struts2标签库
- 简单示例
什么是值栈
- 在struts2里提供的一种存储机制,类似于域对象,可进行存储与取数据
- 在Action中存放数据到值栈中,在jsp页面中进行取值操作
- 值栈的存储位置
1)每次创建Action的时候,就会创建一个Action对象(Action每调用一次创建一次,而Servlet只创建一次)
2)在每个Action对象里只存在一个值栈对象
值栈的结构
- 值栈分为两部分
1)root(一般在root里操作数据)和context
2)root的结构是list,继承自ArrayList
3)context的结构是map,实现了Map接口 - context的结构图
- 在struts.xml配置文件中添加如下内容(必须先访问Action,再访问jsp页面进行查看)
- 在jsp页面中使用
<s:debug></s:debug>
标签
- 页面访问该Action(点击Debug查看值栈的结构,下图是root的结构图)
获取值栈对象
- 注意:每个Action中只存在一个值栈对象
package tqb.valuestack;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.util.ValueStack;
public class Demo1 extends ActionSupport {
@Override
public String execute() throws Exception {
/*
* 获取值栈对象
* 每个Action中拥有一个值栈对象
*/
ActionContext context = ActionContext.getContext();
/*
* 判断值栈对象是否只存在一个
*/
ValueStack stack1 = context.getValueStack();
ValueStack stack2 = context.getValueStack();
System.out.println(stack1 == stack2);//true
return SUCCESS;
}
}
向值栈放数据的三种方式
- 只用值栈对象的set方法
package tqb.valuestack;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.util.ValueStack;
/**
* 向值栈中放数据的三种方式
* 第一种:set方法
* @author tqb
*
*/
public class Demo2 extends ActionSupport {
@Override
public String execute() throws Exception {
/*
* 1.获取值栈对象
*/
ActionContext context = ActionContext.getContext();
ValueStack stack = context.getValueStack();
/*
* 调用值栈对象的set方法(处于栈顶位置)
* 结构:java.util.HashMap
*/
stack.set("username", "lisi");
}
}
- 只用值栈对象的push方法
package tqb.valuestack;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.util.ValueStack;
/**
* 向值栈中放数据的三种方式
* 第二种:push方法
* @author tqb
*
*/
public class Demo2 extends ActionSupport {
@Override
public String execute() throws Exception {
/*
* 1.获取值栈对象
*/
ActionContext context = ActionContext.getContext();
ValueStack stack = context.getValueStack();
/*
* 调用值栈对象的push方法(处于栈顶位置)
* 结构:java.lang.String
*/
stack.push("push...");
return SUCCESS;
}
}
- 在Action中定义变量,生成变量的get方法
package tqb.valuestack;
import com.opensymphony.xwork2.ActionSupport;
/**
* 向值栈中存放数据的第三种方法
* @author tqb
*
*/
public class Demo3 extends ActionSupport {
//定义变量
private String name;
//生成get方法
public String getName() {
return name;
}
@Override
public String execute() throws Exception {
//给变量进行赋值
name="zhangsan";
return SUCCESS;
}
}
向值栈中添加对象
- 定义对象变量
- 生成对象变量的get方法
- 在方法中向变量赋值
package tqb.valuestack;
import com.opensymphony.xwork2.ActionSupport;
import tqb.entity.User;
/**
* 向值栈中添加对象
* @author tqb
*
*/
public class Demo4 extends ActionSupport {
// 定义实体对象
private User user;
// 生成get方法
public User getUser() {
return user;
}
@Override
public String execute() throws Exception {
// 给对象赋值
user = new User();
user.setUsername("wangwu");
user.setPassword("123456");
return SUCCESS;
}
}
向值栈中添加List集合
- 定义list集合变量
- 生成list集合变量的get方法
- 方法内赋值
package tqb.valuestack;
import java.util.ArrayList;
import java.util.List;
import com.opensymphony.xwork2.ActionSupport;
import tqb.entity.User;
/**
* 向值栈中添加list集合
* @author tqb
*
*/
public class Demo5 extends ActionSupport{
// 定义list集合
List<User> list = new ArrayList<User>();
// 生成get方法
public List<User> getList() {
return list;
}
@Override
public String execute() throws Exception {
User user1 = new User();
user1.setUsername("zhangsan");
user1.setPassword("123456");
User user2 = new User();
user2.setUsername("lisi");
user2.setPassword("654321");
list.add(user1);
list.add(user2);
return SUCCESS;
}
}
从值栈中获取数据(采用第三种存放数据的方式)
- 获取字符串
- 获取对象
- 获取list集合(三种方式)
获取set和push方法设置的值
EL表达式为什么可以获取值栈的数据
- 底层对getAttribute方法进行了增强
- 首先在request域获取值,若获取到,则直接返回数据
- 若取不到,则在值栈中查找数据并放到域对象中去
ognl中%、#的使用
- #的使用
1)获取context里面的数据(获取list集合的第三种方式)
2)通过request域放置的数据
- %的使用
1)struts中的表单标签<s:textfield></s:textfield>
2)在struts2标签里面使用ognl表达式,如果直接在struts2表单标签里面使用ognl表达式不识别,只有%之后才会识别
3)实质生成的html代码
<input type="text" name="username" value="具体的值"/>