OGNL概述
1. 之前web阶段学过EL表达式,EL表达式在jsp中获取域对象中的值
2. OGNL是一种表达式,这个表达式功能更加强大
(1) 在struts2里面操作值栈数据
(2) 一般把OGNL在struts2操作,和struts2标签一起使用操作值栈
3. OGNL不是struts2的一部分,但经常和struts2一起使用
(1) 使用OGNL时候首先导入jar包,struts2已经提供
OGNL入门案例
1. 使用ognl+struts2标签实现计算字符串长度
(1) 在Java代码中,调用字符串.length()
2. 使用struts2标签
(1) 使用JSTL时候,导入jar包之外,在jsp页面中引入标签库
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
(2) 使用struts2标签,也要引入标签库
<%@ taglib uri="/struts-tags" prefix="s" %>
(3) 使用struts2标签实现操作
<s:property value="'haha'.length()"/>
什么是值栈
1. 之前在web阶段,在servlet中进行操作,把数据放到域对象里,在页面中使用EL表达式获取到,域对象在一定范围内,存值和取值
2. 在struts2里面提供本身一种存储机制,类似于域对象,是值栈,可以存值和取值
(1) 在action里把数据放到值栈里面,在页面获取到值栈数据
3. Servlet和action的区别
(1) Servlet:默认在第一次访问的时候创建,创建一次对象,单实例对象
(2) Action:访问时候创建,每次访问action都要创建对象,多实例对象
4. 值栈存储位置
(1) 每次访问action时候,都会创建一个action对象,
(2) 在每个action对象里面都会有一个值栈对象
获取值栈对象
1. 获取值栈对象有多种方式
(1) 常用方式:使用ActionContext里面的方法
ActionContext context = ActionContext.getContext();
ValueStack stack1 = context.getValueStack();
2. 每个action中只有一个值栈对象
值栈内部结构
1. 值栈分为两部分
(1) Root,结构是list集合(常用)
(2) context,结构是map结构(很少用)
2. struts2里面标签s:debug,使用它可以查看值栈结构和存储值
(1) 访问action,执行其中的方法,配置返回值到jsp页面中,在页面中使用这个标签。
如访问ValueStackDemoAction时,网页中用s:debug标签显示如下
(2) 在action没有任何操作时,栈顶元素为你访问的action
action对象里有值栈对象,值栈对象里面有action引用
向值栈放数据
1. 向值栈中放数据多种方式
(1) 获取到值栈对象,调用值栈对象里面的set方法
ActionContext context = ActionContext.getContext();
ValueStack stack1 = context.getValueStack();
//调用set方法
stack1.set("boy", "bpf");
(2) 获取值栈对象,调用值栈对象里的push方法
ActionContext context = ActionContext.getContext();
ValueStack stack1 = context.getValueStack();
// 调用push方法
// stack1.push("bpf");
(3) 在action定义变量,生成变量的get方法(最常用)不会分配额外的空间
// 1.定义变量
/private String name;
2.生成变量的get方法
public String getName() {
return name;
}
@Override
public String execute() throws Exception {
/name = "bpf";
return "success";
}
向值栈中放对象
1. 实现步骤
(1) 定义对象变量
(2) 生成变量的get方法
(3) 在执行的方法里面向对象中设置值
//1.定义对象变量
private User user = new User();
//2.生成get方法
public User getUser(){
return user;
}
public String execute() throws Exception {
//3.向值栈的user里面放数据
user.setUsername("bpf");
user.setPassword("123");
return "success";
}
向值栈放list对象
步骤:
(1) 定义list集合变量
(2) 生成变量的get方法
(3) 在执行的方法里面向list集合设置值
//1.定义list变量
private List<User> list = new ArrayList<User>();
//2.get方法
public List<User> getList() {
return list;
}
public String execute() throws Exception {
//3.向list中设置值
User user1 = new User();
user1.setUsername("李逍遥");
user1.setPassword("666");
User user2 = new User();
user2.setUsername("王大力");
user2.setPassword("233");
list.add(user1);
list.add(user2);
return "success";
}
从值栈中获取数据
1. 使用struts2标签和OGNL表达式获取
<s:property value=”OGNL表达式 ”/>
获取字符串
private String username;
public String getUsername() {
return username;
}
@Override
public String execute() throws Exception {
username = "李逍遥";
return "success";
}
<s:property value="username"/>
获取对象
private User user = new User();
public User getUser() {
return user;
}
@Override
public String execute() throws Exception {
user.setUsername("白鹏飞");
user.setPassword("123");
return "success";
}
<s:property value="user.username"/>
<s:property value="user.password"/>
获取list
private List<User> list = new ArrayList<User>();
public List<User> getList() {
return list;
}
@Override
public String execute() throws Exception {
User user1 = new User();
user1.setUsername("李逍遥");
user1.setPassword("666");
User user2 = new User();
user2.setUsername("王大力");
user2.setPassword("233");
list.add(user1);
list.add(user2);
return "success";
}
<h4>第一种方式 :list[i].xxx</h4>
<s:property value="list[0].username"/>
<s:property value="list[0].password"/>
<s:property value="list[1].username"/>
<s:property value="list[1].password"/>
<h4>第二种方式:迭代器 遍历list中的每个user</h4>
<s:iterator value="list">
<s:property value="username"/>
<s:property value="password"/>
</s:iterator>
<h4>第三种方式:迭代器 遍历list中的每个user。新机制:每次遍历出来的user对象放到context中</h4>
<s:iterator value="list" var="user">
<s:property value="#user.username"/>
<s:property value="#user.password"/>
</s:iterator>
其他操作
1. 使用set方法放数据时的获取
<s:property value="boy"/>
2. 使用push方法放数据时的获取
(1) push方法没有名称,只有值
(2) 向值栈放数据,把向值栈中放的数据存到数组里,数组的名称top,根据数组获取值
<s:property value="[0].top"/> //OGNL特殊写法,相当于top[0]
EL表达式获取值栈数据
1. EL表达式获取域对象中的值
2. 向域对象里面放值使用setAttribute方法,获取使用getAttribute方法
3. 底层增强request对象里面的getAttribute方法
(1) 首先从request域中获取值,如果获取到,直接返回
(2) 如果获取不到,就到值栈中把值获取出来放到域对象里
OGNL的#、%的使用
1. #号的使用
(1) 使用#获取context里的值
(2) 演示实例
a. 向request域放值
b. 在页面中使用OGNL表达式获取
@Override
public String execute() throws Exception {
HttpServletRequest request = ServletActionContext.getRequest();
request.setAttribute("req", "hello");
return "success";
}
<s:property value="#request.req"/>
2. %号的使用
(1) 在struts2的标签中表单标签
a.在struts2表单里面使用OGNL表达式,需要写在%之后,否则不识别
<s:textarea name="username" value="%{#request.req}"></s:textarea>