struts2学习_05
一、ognl概述
OGNL是Object-Graph Navigation Language的缩写,它是一种功能强大的表达式语言,通过它简单一致的表达式语法,可以存取对象的任意属性,调用对象的方法,遍历整个对象的结构图,实现字段类型转化等功能。它使用相同的表达式去存取对象的属性。
- EL表达式在jsp页面获取域对象的值
- OGNL是一种表达式,这个表达式功能更加强大
在struts2里面操作值栈数据
一般把ognl在struts2操作:和struts2标签一起使用操作值栈 - OGNL不是struts2的一部分,单独的开源项目,struts2默认表达式为OGNL,经常和struts2一起使用。
- 使用时需要导入ognl的jar包,struts2提供jar包
二、ognl入门案例
1 使用ognl+struts2标签实现计算字符串长度
- 支持对象方法调用
- 在Java代码中,查看字符串长度用`.length()
2 使用struts2标签
(1)使用jstl时,导入jar包之外,还要在jsp页面引入标签库。
使用struts2标签的时候,在jsp中引入标签库
<%@ taglib uri="/struts-tags" prefix="s" %>
(2)使用struts实现操作
<!-- 使用ognl和struts2标签实现计算字符串长度 value属性值:ognl表达式 -->
<s:property value="'hello'.length()"/>
三、值栈
1、web阶段,在servlet里面进行操作,把数据放到域对象里面,在页面中使用el表达式获取到。域对象表示在一定范围内,存值和取值。
2、在struts2里面提供本身一种存储机制,类似于域对象,是值栈,可以存值和取值
- 在action里面把数据放到值栈里面,在页面中获取到值栈数据
3、servlet和action的区别
- Servlet:默认在第一次访问的时候创建,只创建一次,单实例对象
- Action:访问时创建,每次访问action都会创建对象,创建多次,多实例对象
4、值栈存储位置
- 每次访问action时,都会创建action对象
- 在每个action对象里只有一个值栈对象
四、如何获取值栈对象
获取值栈对象的多种方式
1、常用方式:使用ActionContext类里的方法得到值栈对象
//获取ActionContext类的对象
ActionContext context =ActionContext.getContext();
//调用方法得到值栈对象
ValueStack stack = context.getValueStack();
2、使用 Request 对象获取值栈对象
//通过 ServletActionContext 类的静态方法获取 Request 对象
HttpServletRequest request = ServletActionContext.getRequest();
//调用 Request 对象的方法,并传入 ServletActionContext 类的静态常量,获取值栈对象
ValueStack stack = (ValueStack) request.getAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY);
五、值栈的内部结构
值栈包含两大部分,CompoundRoot和context
1、第一部分,CompoundRoot,结构时list集合
2、第二部分,context,常称为contextMap,结构是map集合
- context存储对象引用
key(固定) | value |
---|---|
request | request对象引用 |
session | session对象引用 |
application | application对象引用 |
parameters | 传递相关参数 |
attr |
attr:Attribute,向三个域对象防值,名称都相同setAttribute(“name”,value); 使用attr操作,获取域对象里面的值,获取域范围最小的值
3、struts2里面标签 s:debug,使用这个标签可以查看值栈结构和存储值
- 访问action,执行action的方法有返回值,配置返回值到jsp页面中,在jsp页面中使用这个
s:debug
标签
在页面点击超链接看到结构
- 在action没有做任何操作,栈顶元素是 action引用
action对象里面有值栈对象
值栈对象里面有action引用
六、向值栈放入数据
1 向值栈放数据
1.1、第一种 获取值栈对象,调用值栈对象的set方法
//第一种方式:使用值栈对象的set方法
//获取值栈对象
ActionContext context = ActionContext.getContext();
ValueStack stack = context.getValueStack();
//调用set方法
stack.set("username", "value");
1.2、第二种 获取值栈对象,调用值栈对象的push方法
//获取值栈对象
ActionContext context = ActionContext.getContext();
ValueStack stack = context.getValueStack();
//调用set方法
stack.set("username", "value");
//调用push方法
stack.push("value");
1.3、第三种 在action中定义变量,生成变量的get方法
2、向值栈放对象
- 第一步 定义对象变量
- 第二部 生成变量的get方法
- 在执行的方法里向对象设置值
//1、定义对象变量
private User user = new User();
//生成get方法
public User getUser() {
return user;
}
@Override
public String execute() throws Exception {
//向值栈的user里放数据
user.setUsername("hello");
user.setPassword("123456");
return "success";
}
3、向值栈里放list集合
- 第一步 定义list集合变量
- 第二步 生成变量的get方法
- 执行的方法里面向list集合设置值
//定义list变量
private List<User> list = new ArrayList<User>();
//生成get方法
public List<User> getList() {
return list;
}
@Override
public String execute() throws Exception {
//向list中设置值
User user = new User();
user.setUsername("hello");
user.setPassword("123456");
list.add(user);
return "success";
}
七、从值栈获取数据
使用struts2的标签+ognl表达式获取值栈数据
<s:property value=”ognl表达式”/>
1、获取字符串
- 向值栈放字符串
private String userName;
public String getUserName() {
return userName;
}
@Override
public String execute() throws Exception {
userName = "hello";
return "success";
}
- 在jsp使用struts2标签+ognl表达式获取
<!-- 获取字符串 -->
<s:property value="userName"/>
2、获取对象
- 向值栈放对象
private User user = new User();
//生成get方法
public User getUser() {
return user;
}
@Override
public String execute() throws Exception {
//向值栈的user里放数据
user.setUserName("hello");
user.setPassWord("123456");
return "success";
}
- 在jsp页面中取值
<s:property value="user.userName"/>
<s:property value="user.passWord"/>
3、获取list集合
在值栈中放入list集合
private List<User> list = new ArrayList<User>();
//生成get方法
public List<User> getList() {
return list;
}
@Override
public String execute() throws Exception {
//向list中设置值
User user = new User();
user.setUserName("hello");
user.setPassWord("123456");
list.add(user);
return "success";
}
3.1第一种方式实现获取list集合
<!-- 第一种方式 -->
<s:property value="list[0].userName"/>
<s:property value="list[0].passWord"/>
3.2 第二种方式实现获取list集合
<!-- 第二种方式 -->
<!-- 遍历list集合得到list集合里每个user对象 -->
<s:iterator value="list">
<s:property value="userName"/>
<s:property value="passWord"/>
</s:iterator>
3.3 第三种方式实现获取list集合
<!-- 第三种方式 -->
<!-- 遍历list集合得到list集合里每个user对象 -->
<!-- 机制:把每次遍历出来的user对象放大context里
获取context数据的特点:写ognl表达式,需使用特殊符号#
-->
<s:iterator value="list" var="user">
<s:property value="#user.userName"/>
<s:property value="#user.passWord"/>
</s:iterator>
4、其他方式向值栈存放、获取数据
4.1 使用set方法
//调用set方法设置值
stack.set("username", "value");
<!-- 获取set方法设置的值,根据名称获取 -->
<s:property value="username"/>
4.2 使用push方法
- 使用push方法设置值,没有名称,只有设置的值
- push方法只接收一个Object类型的参数,可以存放任意类型的对象
- push方法是自动将所存的数据转为对应的对象类型,然后存到值栈 top 数组中
<!-- 获取push方法设置的值,通过top数组 -->
<s:property value="[0].top"/>
八、EL表达式获取值栈数据
- EL表达式获取域对象值
- 为什么El表达式可以获取值栈的数据?
- struts2过滤器增强request对象里面的方法getAttribute方法。
在过核心过滤器的时候,对request进行了加强,对request中的getAttribute查找属性方法进行了加强。
如果在request域中找不到数据,会默认到值栈中去查找,把值栈的数据取出来,放到域对象里。
九、ognl表达式#、%的使用
1、#使用
<!-- 遍历list集合得到list集合里每个user对象 -->
<!-- 机制:把每次遍历出来的user对象放大context里
获取context数据的特点:写ognl表达式,需使用特殊符号#
-->
<s:iterator value="list" var="user">
<s:property value="#user.userName"/>
<s:property value="#user.passWord"/>
</s:iterator>
<!-- 获取context中request的值 -->
<!-- #context的key名.域对象名称 (key如request) -->
<s:property value="#request.hello"/>
2、%使用
- 在struts2标签中表单标签
- 在struts2标签里面使用ognl表达式,如果直接在struts2表单标签里面使用ognl表达式不识别,只有%之后才会识别
<s:textfield name="userName" value="%{#request.hello}"></s:textfield>