1 ognl概述
2 ognl入门案例
3 什么是值栈
(1)servlet和action区别
(2)值栈存储位置
- 每个action对象里面有一个值栈对象
- 值栈对象里面有action引用
4 如何获取值栈对象
5 值栈内部结构
(1)root:list集合
(2)context:map集合
6 向值栈放数据
(1)s:debug标签
(2)向值栈放字符串
(3)向值栈放对象
(4)向值栈放list集合
- set方法
- push方法
- 定义变量,get方法
7 从值栈获取数据
(1)从值栈获取字符串
(2)从值栈获取对象
(3)从值栈获取list集合
- s:iterator标签使用
8 EL表达式获取值栈数据
(1)增强request里面getAttribute方法
9 ognl表达式 #、%使用
1 之前web阶段,学习过EL表达式,EL表达式在jsp中获取域对象里面的值;ognl可以任意存取对象的属性或者调用对象的方法,能够遍历整个对象的结构图,实现对象属性类型的转换等功能。它使用相同的表达式去存取对象的属性。
2 OGNL是一种表达式,这个表达式功能更加强大,
(1)在struts2里面操作值栈数据
(2)一般把ognl在struts2操作:和struts2标签一起使用操作值栈
3 OGNL不是struts2的一部分,单独的项目,经常和struts2一起使用
使用ognl时候首先导入jar包,struts2提供jar包
4.三要素
表达式;根对象,Context对象
1 使用ognl+struts2标签实现计算字符串长度
在java代码中,调用字符串.length();
2 使用struts2标签
(1)使用jstl时候,导入jar包之外,在jsp页面中引入标签库
使用struts2标签时候,在jsp中引入标签库
<%@ taglib prefix="s" uri="/struts-tags" %>
(2)使用struts2标签实现操作
1 之前在web阶段,在servlet里面进行操作,把数据放到域对象里面,在页面中使用el表达式获取到,域对象在一定范围内,存值和取值
2 在struts2里面提供本身一种存储机制,类似于域对象,是值栈,可以存值和取值
(1)在action里面把数据放到值栈里面,在页面中获取到值栈数据
3 servlet和action区别
(1)Servlet:默认在第一次访问时候创建,创建一次,单实例对象
(2)Action:访问时候创建,每次访问action时候,都会创建action对象,创建多次,多实例对象
4 值栈存储位置
(1)每次访问action时候,都会创建action对象,
(2)在每个action对象里面都会有一个值栈对象(只有一个)
常用方式:使用ActionContext类里面的方法得到值栈对象
// 1 获取ActionContext类的对象 ActionContextcontext = ActionContext.getContext(); //2 调用方法得到值栈对象 ValueStack stack1 = context.getValueStack();2 每个action对象中只有一个值栈对象
栈:
第一部分 root,结构是list集合
(1)一般操作都是root里面数据
第二部分 context,结构map集合
s:debug,使用这个标签可以查看值栈结构和存储值
(1)访问action,执行action的方法有返回值,配置返回值到jsp页面中,在jsp页面中使用这个标签 [Debug]
点击超链接看到结构,基本看 root 就行了。
(2)在action没有做任何操作,栈顶元素是 action引用
- action对象里面有值栈对象
- 值栈对象里面有action引用
若想访问 ObjectStack 里的某个对象的属性. 可以使用以下几种形式之一:
ObjectStack里的对象可以通过一个从零开始的下标来引用. ObjectStack 里的栈顶对象可以用 [0] 来引用, 它下面的那个对象可以用 [1] 引用. 若希望返回栈顶对象的 message 属性值: [0].message 或 [0][“message”] 或 [0][‘message’]
若在指定的对象里没有找到指定的属性, 则到指定对象的下一个对象里继续搜索. 即 [n] 的含义是从第 n 个开始搜索, 而不是只搜索第 n 个对象
若从栈顶对象开始搜索, 则可以省略下标部分
username: ^<s:property value="[0].username"/>
若想访问ContextMap 里的某个对象的属性, 可以使用以下几种形式之一:
返回 session 中的 code 属性: #session.code
返回 request 中的 customer 属性的 name 属性值: #request.customer.name
返回域对象(按 request, session, application 的顺序)的lastAccessDate 属性:#attr.lastAccessDate
获取值栈对象,调用值栈对象里面的 set 方法
@Override public String execute() throws Exception { //第一种方式使用值栈对象里面的 set方法 //1 获取值栈对象 ActionContextcontext = ActionContext.getContext(); ValueStackstack = context.getValueStack(); //2 调用方法set方法 stack.set("username","老兰"); return "success"; }获取值栈对象,调用值栈对象里面的 push方法
在action定义变量,生成变量的get方法—常用
//第三种方式 //定义变量 private String name; //生成 get 方式 public String getName(){ return name; } @Override public String execute() throws Exception { name = "老兰"; return "success"; }
使用场景:以前做修改操作时,会把数据放到域对象中
1 实现步骤,第三种方式
第一步 定义对象变量
第二步 生成变量的get方法
第三步 在执行的方法里面向对象中设置值
public classObjectDemoAction extends ActionSupport { //1 定义对象变量 private User user = new User(); //2 生成get方法 public User getUser() { return user; } public String execute() throws Exception { //3 向值栈的user里面放数据 user.setUsername("lucy"); user.setPassword("123"); user.setAddress("美国"); return "success"; } }第一步 定义list集合变量
第二步 生成变量的get方法
第三步 在执行的方法里面向list集合设置值
public classListDemoAction extends ActionSupport { // 1 定义list变量 private List<User> list = newArrayList<User>(); // 2 get方法 public List<User>getList() { return list; } public String execute() throws Exception { //3 向list中设置值 Useruser1 = newUser(); user1.setUsername("小奥"); user1.setPassword("123"); user1.setAddress("美国"); Useruser2 = newUser(); user2.setUsername("小王"); user2.setPassword("250"); user2.setAddress("越南"); list.add(user1); list.add(user2); return "success"; } }
使用struts2的标签+ognl表达式获取值栈数据
<s:propertyvalue=”ognl表达式”/>
不要忘了在struts.xml中的配置
·利用 OGNL 调用任何一个 Java 类里的静态字段或方法;被压入到 ValueStack 栈的对象上的公共字段和方法.
默认情况下, Struts2 不允许调用任意 Java 类静态方法, 需要重新设置struts.ognl.allowStaticMethodAccess 标记变量的值为 true.
调用一个实例字段或方法的语法, 其中 object 是Object Stack 栈里的某个对象的引用:
.object.fieldName: [0].datePattern
.object.methodName(argumentList): [0].repeat(3, “Hello”);
<li>访问值栈中的action的普通属性: username = <s:property value="username"/> </li> <li>访问值栈中对象的普通属性(get set方法):<s:property value="user.age"/> | <s:property value="user['age']"/> | <s:property value="user[\"age\"]"/> | wrong: <%--<s:propertyvalue="user[age]"/>--%></li> <li>访问值栈中对象的普通属性(get set方法): <s:property value="cat.friend.name"/></li> <li>访问值栈中对象的普通方法:<s:property value="password.length()"/></li> <li>访问值栈中对象的普通方法:<s:property value="cat.miaomiao()"/></li> <li>访问值栈中action的普通方法:<s:property value="m()"/></li> <hr /> <li>访问静态方法:<s:property value="@com.bjsxt.struts2.ognl.S@s()"/></li> <li>访问静态属性:<s:property value="@com.bjsxt.struts2.ognl.S@STR"/></li> <li>访问Math类的静态方法:<s:property value="@@max(2,3)"/></li>
1 向值栈放字符串
public classValueStackAction extends ActionSupport { private String username; public String getUsername() { return username; } @Override public String execute() throws Exception { username = "老兰"; return "success"; } }2 在jsp使用struts2标签+ognl表达式获取
获取字符串的值<br />
<s:property value="username"/>
1 向值栈放对象
public classValueStackObjectAction extends ActionSupport { private User user = new User(); public User getUser() { return user; } @Override public String execute() throws Exception { user.setUsername("mary"); user.setPassword("250"); user.setAddress("china"); return "success"; } }2 在页面中获取值
<br />获取对象的值<br /> <s:property value="user.username"/> <s:property value="user.password"/> <s:property value="user.address"/>数组型属性:各个元素以逗号分隔, 并且不带方括号
下标 fun[0]
length字段: fun.length
类似list:以逗号分隔, 并且带方括号
下标:· colors[0] 指定元素
size方法或关键字 size: colors.size或 colors.size() 长度
isEmpty()方法或关键字 isEmptycolors.isEmpty 或 colors.isEmpty() 为空
还可以使用 OGNL 表达式来创建 List, 创建一个 List 与声明一个 Java 数组是相同的: {“Red”, “Black”, “Green”}
<li>访问List:<s:property value="users"/></li> <li>访问List中某个元素:<s:property value="users[1]"/></li> <li>访问List中元素某个属性的集合:<s:property value="users.{age}"/></li> <li>访问List中元素某个属性的集合中的特定值:<s:property value="users.{age}[0]"/> | <s:property value="users[0].age"/></li> <li>访问Set:<s:property value="dogs"/></li> <li>访问Set中某个元素:<s:property value="dogs[1]"/></li>
下标: map[key]
size或 size()
isEmpty或 isEmpty() 是不是空.
<li>访问Map:<s:property value="dogMap"/></li> <li>访问Map中某个元素:<s:property value="dogMap.dog101"/> | <s:property value="dogMap['dog101']"/> | <s:property value="dogMap[\"dog101\"]"/></li> <li>访问Map中所有的key:<s:property value="dogMap.keys"/></li> <li>访问Map中所有的value:<s:property value="dogMap.values"/></li>
<li>投影(过滤):<s:property value="users.{?#this.age==1}[0]"/></li> <li>投影:<s:property value="users.{^#this.age>1}.{age}"/></li> <li>投影:<s:property value="users.{$#this.age>1}.{age}"/></li> <li>投影:<s:property value="users.{$#this.age>1}.{age}== null"/></li>
获取set方法设置的值 根据名称获取值 <br/>
<s:property value="username"/>
(1)使用push方法设置值,没有名称,只有设置的值
(2)向值栈放数据,把向值栈放数据存到数组里面,数组名称 top,根据数组获取值
获取push方法设置的值 <br/>
<s:property value="[0].top"/>
1 EL表达式获取域对象值
使用foreach标签+el表达式获取值栈list集合数据<br/>
<c:forEach items="${list }" var="user"> ${user.username} ${user.password} ${user.address} <br/> </c:forEach>2 向域对象里面放值使用setAttribute方法,获取值使用getAttribute方法
3 底层增强request对象里面的方法getAttribute方法
(1)首先从request域获取值,如果获取到,直接返回
(2)如果从request域获取不到值,到值栈中把值获取出来,把值放到域对象里面
4 查看源代码
1 使用#获取context里面数据—会此就行
2 演示# 操作
(1)向request域放值
(2)在页面中使用ognl获取
在struts2标签里面使用ognl表达式,如果直接在struts2表单标签里面使用ognl表达式不识别,只有%之后才会识别。
访问root属性时:
Jsp:
源代码文件:http://download.csdn.net/detail/qq_26553781/9778694