一. ognl概述
1. 在web阶段,学习过EL表达式,EL表达式在JSP中获取域对象里面的值
2. ognl是一种表达式,这个表达式功能更加强大
i.在struts2里面操作值栈数据
ii. 一般把ognl在struts2操作,和struts2标签一起使用操作值栈
3. OGNL不是struts2的一部分,单独的项目,经常和struts2一起使用
i. 使用ognl时候首先要导入jar包,struts2提供的jar包
二. ognl入门案例
1. 使用ognl+struts2标签实现计算字符串长度
支持对象方法的调用,例如 objName.methodName()i. 在Java代码中调用字符串 .length() 方法
2. 使用struts2标签
i. 使用jstl时候,导入jar包后,在jsp页面中引入标签库
ii. 使用struts2标签的时候,在jsp页面中引入标签库
<%@ taglib uri="/struts-tag" prefix="s" %> <!--引入标签库 -->
iii. 使用struts2标签 实现操作
<body> <!-- 使用ognl+struts2标签实现字符串长度 value属性值:ognl表达式 --> <s:property value="'abcdefg'.length()"/> </body>
三. 值栈
1. 什么是值栈?
i. 之前在web阶段,在servlet里面进行操作,把数据放到域对象里面,在页面中使用EL表达式获取到,域对象在一定范围内,存值和取值。
ii. 在struts2里面提供本身一种存储的机制,类似于域对象,是值栈,可以存值和取值
1) 在action里面把数据放到值栈里面,在页面里面获取到值栈数据
iii. action和servlet区别?
1) servlet:默认在第一访问时候创建,创建一次,单实例对象。2) action:访问时候创建,每次访问action,都会创建action对象,创建多次,多实例对象。
iv. 值栈存储位置
1) 每次访问action时候,都会创建action对象。2) 在每个action对象里面都有一个值栈对象。
四. 如何获取值栈对象
1. 获取值栈对象有多种方式
i. 使用ActionContext类里面的方法得到值栈对象。
//1.获取ActionContext对象 ActionContext context = ActionContext.getContext(); //2.调用方法得到值栈对象 ValueStack stack1 = context.getValueStack();
ii. 每一个action对象中只有一个值栈对象
五. 值栈内部结构
1. 值栈分为两部分
i. 第一部分 root,结构是 list集合
1) 一般操作都是 root里面的数据
ii. 第二部分 context,结构是 map集合
2. struts2里面标签 s:debug 使用这个标签可以查看值栈结构和存储值
i. 访问action,执行action的方法有返回值,配置返回值到 jsp页面中,在 jsp页面中使用这个标签
1) 点击超链接看到结构
ii. 在acion没有做任何操作,栈顶元素是action 引用
1) action 对象里面有值栈对象2) 值栈对象里面有action引用
六. 向值栈放数据
1. 向值栈放数据的多种方式
i. 获取值栈对象,调用值栈对象里面的 set 方法
//第一种 使用值栈对象里面的set方法 //1.获取值栈对象 ActionContext context = ActionContext.getContext(); ValueStack stack1 = context.getValueStack(); //2.调用方法set方法 stack1.set("username", "yangfan");
ii. 获取值栈对象,调用值栈对象里面的 push方法
//第一种 使用值栈对象里面的set方法 //1.获取值栈对象 ActionContext context = ActionContext.getContext(); ValueStack stack1 = context.getValueStack(); //2.调用方法set方法 stack1.set("username", "yangfan"); //3.调用方法push方法 stack1.push("abc");
iii. 在action 定义变量,生成变量的get方法(主要)
public class ValueStackAcion extends ActionSupport { //1.定义变量 private String name; //2.生成变量get方法 public String getName() { return name; } @Override public String execute() throws Exception { //在执行方法里面向变量设置值 name = "hello"; return "success"; } }
2. 向值栈放对象
i. 定义对象变量ii. 生成变量的get方法iii. 在执行的方法里面向对象中设置值
import org.fan.entity.User; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionSupport; import com.opensymphony.xwork2.util.ValueStack; public class ObjectAcion extends ActionSupport { //1.定义对象变量 private User user = new User(); //2.生成get方法 public User getUser() { return user; } @Override public String execute() throws Exception { //3.向值栈的User里面放数据 user.setUsername("yangfan"); user.setPassword("123123"); user.setAddress("西安"); return "success"; } }
3. 向值栈放 list集合
i. 定义list集合变量ii. 生成变量的get方法iii. 在执行的方法里面向list集合设置值
import java.util.ArrayList; import java.util.List; import org.fan.entity.User; import com.opensymphony.xwork2.ActionSupport; public class ListAction extends ActionSupport { //1.定义List变量 private List<User> list = new ArrayList<>(); //2.get方法 public List<User> getList() { return list; } @Override public String execute() throws Exception { //3.向list里面放值 User user1 = new User(); user1.setUsername("Ying"); user1.setPassword("123456"); user1.setAddress("北京"); User user2 = new User(); user2.setUsername("yangfan"); user2.setPassword("123123"); user2.setAddress("西安"); list.add(user1); list.add(user2); return "success"; } }
七. 从值栈获取数据
使用struts2标签+ognl表达式获取值栈数据
<s:property value="ognl表达式"/>
1. 从值栈获取字符串
i. 向值栈中放字符串
import com.opensymphony.xwork2.ActionSupport; public class ValueStackAction extends ActionSupport { private String username; public String getUsername() { return username; } public String execute() throws Exception { username = "itcast"; return "success"; } }
ii. 在jsp中使用struts2标签+ognl表达式获取
<!-- 1.获取字符串的值 --> <s:property value="username"/>
2. 从值栈获取对象
i. 向值栈中放对象
import org.fan.entity.User; import com.opensymphony.xwork2.ActionSupport; public class ObjectStackAction extends ActionSupport { private User u = new User(); public User getU() { return u; } public String execute() throws Exception { u.setUsername("yang"); u.setPassword("123123"); u.setAddress("西安"); return "success"; } }
ii. 在页面中获取
<!-- 2.获取对象 --> <s:property value="u.username"/> <s:property value="u.password"/> <s:property value="u.address"/>
3. 从值栈获取 list集合
i. action
import java.util.ArrayList; import java.util.List; import org.fan.entity.User; import com.opensymphony.xwork2.ActionSupport; public class ListStackAction extends ActionSupport { //1.定义list变量 private List<User> list = new ArrayList<>(); //2.get方法 public List<User> getList() { return list; } public String execute() throws Exception { //3.向list放数据 User user1 = new User(); user1.setUsername("Ying"); user1.setPassword("123456"); user1.setAddress("北京"); User user2 = new User(); user2.setUsername("yangfan"); user2.setPassword("123123"); user2.setAddress("西安"); list.add(user1); list.add(user2); return "success"; } }
ii. jsp
<!-- 3.获取值栈中 list集合数据 --> 第一种方式 <br> <s:property value="list[0].username"/> <s:property value="list[0].password"/> <s:property value="list[0].address"/><br> <s:property value="list[1].username"/> <s:property value="list[1].password"/> <s:property value="list[1].address"/><br> 第二种方式 <br> <!-- 使用struts2里面的标签 类似JSTL里面的 foreach标签 --> <!-- 遍历list得到list里面每个user对象--> <s:iterator value="list"> <s:property value="username"/> <s:property value="password"/> <s:property value="address"/><br> </s:iterator> 第三种方式 <br> <!--遍历值栈list集合 得到每个对象 机制:把每次遍历出来的user对象放到context里面 获取context里面数据的特点:写ognl表达式,使用特殊符号 # --> <s:iterator value="list" var="user"> <s:property value="#user.username"/> <s:property value="#user.password"/> <s:property value="#user.address"/><br> </s:iterator>
4.其他操作
i. 使用set方法向值栈放的数据的获取
ii. 使用push方法向值栈放数据的获取
1) 使用push方法设置值,没有名称,就只有设置的值。
2) 向值栈中放数据,把向值栈中放的数据存到数组中,数组名称 top,根据数组获取值。
八. EL表达式获取值栈数据(为什么?)
1. EL表达式获取域对象
2. 向域对象里面放值使用setAttribute方法,获取值使用getAttribut方法
3. 底层增强request对象里面的方法getAttribute方法
i. 首先从request域获取值,如果获取到,直接返回。
ii. 如果从request域获取不到值,到值栈中把值获取出来,把值放到域对象里面。
4. 关键性源代码
九. ognl表达式 #、% 使用
1. # 的使用
i. 使用#获取context里面数据
ii. # 操作
1) java
import javax.servlet.http.HttpServletRequest; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwork2.ActionSupport; public class ContextAction extends ActionSupport { @Override public String execute() throws Exception { //1.获取request HttpServletRequest request = ServletActionContext.getRequest(); request.setAttribute("req", "123123"); return "success"; } }
2) jsp
<!-- 获取context里面数据 写ognl时候 首先添加符号 # #context的key的名称.域对象名称 --> <s:property value="#request.req"/>
2. % 的使用
i. 在struts2标签中使用ognl表达式,如果直接在struts2表单标签里面使用ognl表达式不识别,只有 % 之后才会识别。
<s:textfield name="username" value="%{#request.req}"></s:textfield>