Struts框架笔记03_OGNL表达式与值栈
1. OGNL
1.1 OGNL概述
1.1 什么是OGNL
- OGNL是Object-Graph Navigation Language的缩写,它是一种功能强大的表达式语言,通过它简单一致的表达式语法,可以存取对象的任意属性,调用对象的方法,遍历整个对象的结构图,实现字段类型转化等功能。它使用相同的表达式去存取对象的属性。
- OGNL:对象导航语言,可以方便地操作对象属性的开源表达式语言,使页面更简洁;比EL表达式强大很多倍。可以调用Struts2的值栈的数据。OGNL其实第三方的表达式语言。
- EL:从域对象中获取数据,或者从EL的11个对象中获取。
1.1.2 OGNL的优势
Struts 2默认的表达式语言是OGNL,原因是它相对其它表达式语言具有下面几大优势:
支持对象方法调用,如xxx.doSomeSpecial();
支持类静态的方法调用和值访问,表达式的格式为@[类全名(包括包路径)]@[方法名 | 值名],例如:@java.lang.String@format('foo %s', 'bar')或@tutorial.MyConstant@APP_NAME;
支持赋值操作和表达式串联,如price=100, discount=0.8, calculatePrice(price*discount),这个表达式会返回80;
访问OGNL上下文(OGNL context)和ActionContext;
操作集合对象。
可以直接new一个对象
1.1.2 OGNL使用的要素
- 表达式
- 根对象
- Context对象
1.2 OGNL的Java环境入门【了解】
1.2.1 访问对象的方法
@Test // OGNL调用对象的方法
public void test1() throws OgnlException {
// 获得context
OgnlContext context = new OgnlContext();
// 获得根对象
Object root = context.getRoot();
// 执行表达式
Object object = Ognl.getValue("'helloworld'.length()", context, root);
System.out.println(object);//10
}
1.2.2 访问对象的静态方法
@Test // OGNL访问对象的静态方法
public void test2() throws OgnlException {
// 获得context
OgnlContext context = new OgnlContext();
// 获得根对象
Object root = context.getRoot();
// 执行表达式@类名@方法名
Object object = Ognl.getValue("@java.lang.Math@random()", context, root);
System.out.println(object);// 0-1的随机数
}
1.2.3 获得Root中的数据
@Test // 访问Root中的数据,不需要加#
public void test3() throws OgnlException {
// 获得context
OgnlContext context = new OgnlContext();
// 执行表达式
User user = new User("aaa", "123");
context.setRoot(user);
// 获得根对象
Object root = context.getRoot();
Object username = Ognl.getValue("username", context,root);
Object password = Ognl.getValue("password", context,root);
System.out.println(username+" "+password);
}
1.2.4 获得OgnlContext中的数据
@Test // 访问Context中的数据,需要加#
public void test4() throws OgnlException {
// 获得context
OgnlContext context = new OgnlContext();
// 获得根对象
Object root = context.getRoot();
// 向context中存入数据
context.put("name", "张三");
// 执行表达式
Object object = Ognl.getValue("#name", context, root);
System.out.println(object);
}
1.3 OGNL的Struts2的环境入门
1.3.1 访问对象的方法
- 在web.xml文件中配置核心过滤器
<!-- 配置核心过滤器 -->
<filter>
<filter-name>struts</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
- 引入struts核心配置文件
- 编写一个JSP../WebContent/demo1/test.jsp,引入struts的标签库
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="/struts-tags" prefix="s"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>OGNL在Struts2环境中的入门</h1>
<h3>调用对象的方法</h3>
<s:property value="'struts'.length()"/>
</body>
</html>
1.3.2 访问对象的静态方法
- 静态方法访问在Struts2中默认是关闭的,需要手动开启一个常量
- 在配置文件中开启常量
<struts>
<!-- 开启静态方法 -->
<constant name="struts.ognl.allowStaticMethodAccess" value="true"></constant>
</struts>
- JSP
<h1>OGNL在Struts2环境中的入门</h1>
<h3>调用对象的方法</h3>
<s:property value="'struts'.length()"/>
<h3>调用对象的静态方法</h3>
<!-- 静态方法访问在Struts2中默认是关闭的,需要手动开启一个常量 -->
<s:property value="@java.lang.Math@random()"/>
- 测试:访问jsp页面,能正常显示
struts
的长度和产生的随机数
2. 值栈
2. 1什么是值栈
- 值栈ValueStack是Struts的一个接口。OgnlValueStack是ValueStack的实现类,客户端发送一个请求struts2架构会创建一个action实例同时创建一个OgnlValueStack值栈实例,OgnlValueStack贯穿整个Action生命周期,struts2中使用OGNL将请求Action的参数封装为对象存储到值栈中,并通过OGNL表达式读取值栈中的对象属性值。
- 值栈其实类似于一个数据中转站,Struts2中的数据都保存到了值栈中。
- request域中的数据只能在jsp页面中取出,但是值栈中的数据可以在jsp页面、Action、配置文件中取出。
2.2 值栈的内部结构
- ValueStack中有两个主要的区域:
- root区域:其实就是一个ArrayList。里面一般放置对象。获取root数据需要加#。
- context区域:其实就是一个Map。放置的是web开发的常用对象数据的引用。获取context数据需要加#。
- request
- session
- application
- attr
- 所说的操作值栈,通常指的是操作ValueStack中的root区域。
2.3 值栈与ActionContext的关系
- ActionContext:Action的上下文
- 通过源码可以看到。当前请求过来的时候,执行过滤器中doFilter方法,在这个方法中创建ActionContext,在创建ActionContext过程中,也创建了ValueStack对象,并且将ValueStack对象传递给ActionContext对象。所以可以通过ActionContext获取值栈对象。
- ActionContext对象之所以能够访问Servlet的API(访问的是域对象的数据)是由于其内部有值栈的引用。
2.4 获得值栈
package com.itzhouq.struts.valueStack;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.util.ValueStack;
/**
* 获得值栈的方式
* @author itzhouq
*
*/
public class ValueStackDemo1 extends ActionSupport {
@Override
public String execute() throws Exception {
// 方式一:
ValueStack valueStack1 = ActionContext.getContext().getValueStack();
// 方式二:
ValueStack valueStack2 = (ValueStack) ServletActionContext.getRequest().getAttribute("struts.valueStack");
// 一个Action的实例,只会创建一个ValueStack的对象
System.out.println(valueStack1 == valueStack2);//true
return NONE;
}
}
2.5 操作值栈
- 操作值栈----向值栈中存储数据
2.5.1 方式一:在Action中提供属性的get方法的方式
默认情况下,将Action对象压入到值栈。Action的属性也会在值栈中。
编写Action类ValueStackDemo2
package com.itzhouq.struts.valueStack; import com.itzhouq.struts.domain.User;
import com.opensymphony.xwork2.ActionSupport; /**
* 操作ValueStack,方式一:利用Action本身在值栈中的特性
* @author itzhouq
*
*/
public class ValueStackDemo2 extends ActionSupport {
private User user; public User getUser() {
return user;
}
@Override
public String execute() throws Exception {
// 向ValueStack中存储数据
user = new User("李斌","456");
return SUCCESS;
}
}
在配置文件中配置
action name="valueStackDemo2" class="com.itzhouq.struts.valueStack.ValueStackDemo2">
<result>/demo1/success.jsp</result>
</action>
跳转页面success.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="/struts-tags" prefix="s"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>查看值栈的内部结构</h1>
<s:debug></s:debug>
<!-- 方式一的获取:利用Action在值栈中的特性 -->
<s:property value="user.username"/>
<s:property value="user.password"/> </body>
</html>
访问http://localhost/Struts2_day03/valueStackDemo2.action
2.5.2 使用ValueStack中本身的方法的方式
编写Action类ValueStackDemo3
package com.itzhouq.struts.valueStack; import com.itzhouq.struts.domain.User;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.util.ValueStack; /**
* 操作值栈:方式二:调用值栈中的方法实现
* @author itzhouq
*
*/
public class ValueStackDemo3 extends ActionSupport{
@Override
public String execute() throws Exception {
// 向值栈中保存数据:
// 获得值栈对象
ValueStack valueStack = ActionContext.getContext().getValueStack();
// 使用push(Object obj); set(String key, Object obj);
User user = new User("李世民","26");
// 现在user在栈顶的位置
valueStack.push(user);
valueStack.set("name", "赵子龙");// 创建一个Map集合,将Map压入到栈中
return super.execute();
}
}
在配置文件中配置,跳转页面success.jsp
<h1>操作值栈</h1>
<s:debug></s:debug>
<!-- 方式一的获取:利用Action在值栈中的特性 -->
<%-- <s:property value="user.username"/>
<s:property value="user.password"/> --%> <!-- 方式二的获取:调用valueStack的本身的方法 -->
<s:property value="username"/>
<s:property value="password"/> <s:property value="name"/>
访问http://localhost/Struts2_day03/valueStackDemo3.action
2.6 获得值栈数据
获取值栈中的数据就是在页面中使用OGNL表达式
- 获取root的数据,不需要加#
- 获取context中的数据,需要加#
编写Action了ValueStackDemo4
package com.itzhouq.struts.valueStack; import java.util.ArrayList;
import java.util.List; import org.apache.struts2.ServletActionContext; import com.itzhouq.struts.domain.User;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport; /**
* 获取值栈的数据
* @author itzhouq
*
*/
public class ValueStackDemo4 extends ActionSupport{
@Override
public String execute() throws Exception {
// 向值栈中保存一个对象
User user = new User("aaa", "111");
ActionContext.getContext().getValueStack().push(user); // 向值栈中保存一个集合
List<User> list = new ArrayList<User>();
list.add(new User("aaa","111111"));
list.add(new User("bbb","222222"));
list.add(new User("ccc","333333"));
ActionContext.getContext().getValueStack().set("list", list); // 向context中存入数据
ServletActionContext.getRequest().setAttribute("name", "r李斌");
ServletActionContext.getRequest().getSession().setAttribute("name", "s赵红");
ServletActionContext.getServletContext().setAttribute("name", "a邓子龙"); return super.execute();
}
}
在主配置文件中配置Demo4,编写跳转页面success2.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="/struts-tags" prefix="s"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>获取值栈的数据</h1>
<s:debug></s:debug>
<!--获取一个对象的数据 -->
<s:property value="username"/>
<s:property value="password"/>
<br><br> <!-- 获取集合中数据 -->
<s:property value="list[0].username"/>
<s:property value="list[0].password"/><br>
<s:property value="list[1].username"/>
<s:property value="list[1].password"/><br>
<s:property value="list[2].username"/>
<s:property value="list[2].password"/><br> <br><br>
<!-- 获取context中的数据 -->
<s:property value="#request.name"/><br>
<s:property value="#session.name"/><br>
<s:property value="#application.name"/><br>
</body>
</html>
测试:访问http://localhost/Struts2_day03/valueStackDemo4.action
2.7 EL为何能访问值栈的数据
- 因为Struts2的框架的底层对
request.getAttribute(String name);
进行了增强。
3. OGNL中的特殊字符
3.1 #号
3.1.1 获取context的数据
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="/struts-tags" prefix="s"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>#的用法</h1>
<%
request.setAttribute("name", "李斌");
%>
<s:property value="#request.name"/>
<hr>
</body>
</html>
- 在页面能获取到request中存储的数据
3.1.2 使用#号构建List
或map
集合
- ../WebContent/demo2/test.jsp
<h3>构建list集合</h3>
<s:iterator var="i" value="{'aa','bb','cc'}">
<s:property value="i"/> -- <s:property value="#i"/> <br>
</s:iterator>
<h3>构建Map集合1</h3>
<s:iterator value="#{'aa':'11111', 'bb':'22222', 'cc':'33333' }">
<s:property value="key"/>--<s:property value="value"/><br>
</s:iterator>
<h3>构建Map集合2</h3>
<s:iterator var="entry" value="#{'aa':'11111', 'bb':'22222', 'cc':'33333' }">
<s:property value="#entry.key"/>--<s:property value="#entry.value"/><br>
</s:iterator>
<h3>实例1</h3>
<s:radio list="{'男', '女' }" name="sex1" label="性别"/><br>
<h3>实例2</h3>
<s:radio list="#{'1':'男','2': '女' }" name="sex2" label="性别"/>
访问http://localhost/Struts2_day03/demo2/test.jsp
3.2 %号
强制解析成OGNL表达式
../WebContent/demo2/test2.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="/struts-tags" prefix="s"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h3>%的使用</h3>
<%
request.setAttribute("name", "罩子龙");
%>
姓名:<s:textfield name="name" value="%{#request.name}"/>
</body>
</html>
3.3 $号
- 在配置文件中使用
$
。
Struts框架笔记03_OGNL表达式与值栈的更多相关文章
- struts框架问题六之从值栈中获取值
6. 问题六: 在JSP中获取值栈的数据 * 总结几个小问题: > 访问root中数据 不需要# > 访问context其它对象数据 加 # > 如果向root中存入对象的话,优先使 ...
- struts框架问题五之向值栈中保存数据
5. 问题五: 向值栈保存数据 (主要针对root栈) > valueStack.push(Object obj); * push方法的底层调用root对象的push方法(把元素添加到0位置) ...
- Struts2之 OGNL表达式和值栈
技术分析之OGNL表达式概述(了解) 1. OGNL是Object Graphic Navigation Language(对象图导航语言)的缩写 * 所谓对象图,即以任意 ...
- EL表达式获取值栈数据
---------------------siwuxie095 EL 表达式获取值栈数据 1.导入 JSTL 相关包,下载链接: (1)http://tomcat.apache.org/taglibs ...
- Struts2-从值栈中获取数据-EL表达式从值栈获取
从值栈获取数据 1 使用struts2的标签+ognl表达式获取值栈数据 (1)<s:property value=”ognl表达式”/> 获取字符串
- Struts2_day03--从值栈获取数据_EL表达式获取值栈数据(为什么)
从值栈获取数据 1 使用struts2的标签+ognl表达式获取值栈数据 (1)<s:property value=”ognl表达式”/> 获取字符串 1 向值栈放字符串 2 在jsp使用 ...
- struts框架中OGNL表达式的使用之jsp页面获取action中的属性值
在jsp页面中获取action中的值: 1.写一个action类OgnlAction类: 需要注意的地方: 如果在aciton中直接使用ognl表达式,将值存储的值栈中,是不能通过跳转将值传到jsp页 ...
- Struts工作机制图+OGNL+EL+值栈(Map,对象栈)
struts 值栈 通过get set方法 方便的获取,设置属性值 比如从jsp页面传来的參数...从Action设置jsp所要回显的内容 注意EL表达式,struts2对request进 ...
- struts2(四) ognl表达式、值栈、actionContext之间的关系
今天来说说ognl表达式在struts2中的运用. --wh 一.什么是Ognl? 通过百度百科查询到的解释,其中详细的说明了OGNL的作用. 下面我们就对OGNL这5个作用进行讲解 1.存取对象的任 ...
随机推荐
- redis 使用redis Desktop manger进行远程进行链接
1.修改redis.conf文件: a.去掉bind:127.0.0.0 b.protected mode 模式改成 no 2.重启redis /etc/init.d/redis restart 3. ...
- Excel 如何查找 问号 “?” 、星号“*” 、 “~”号
若需要查找问号“?”,则在查找内容文本框中输入“~?”.“?”为通配符,代替单个任意字符,如果直接查找,会找到包含数据的所有单元格. 若需要查找星号“*”,则在查找内容文本框中输入“~*”.“*”为通 ...
- 【Redis】Redis 事务
Redis 事务介绍 Redis 事务可以一次执行多个命令, 并且带有以下三个重要的保证: 批量操作在发送 EXEC 命令前被放入队列缓存. 收到 EXEC 命令后进入事务执行,事务中任意命令执行失败 ...
- Ubuntu 配置镜像源
Ubuntu 配置镜像源 注, 如果添加镜像后没有自己要安装的软件, 切回原镜像即可, 只是有点慢. cp /etc/apt/sources.list /etc/apt/sources.list.ba ...
- 系统运维工程师装逼完全指南(转载Mark)
1.全球化的认证有助于提升逼格,什么OCM.CCIE.RHCA.CISSP等等能考都考,再不济,也要有一张系统架构设计师或者网络规划设计师的信产部认证.每过一个认证,逼格提升一档. 2.TCP/IP协 ...
- centos7 intall nvidia driver
此教程是介绍于 CentOS 7 以上的 Linux 系统中安装 NVIDIA 显卡驱动和 CUDA Toolkit .此文中以 CentOS 7.4 64 bit 为例,显卡型号为 NVIDIA T ...
- java学习笔记(5)-排序(1)
标签(空格分隔): 学习笔记 1. 冒泡 public class MaoPao{ public static void sort(int[] arr){ for(int i=arr.length-1 ...
- linux shell 获取文件夹全文绝对路径
在ls中列出文件的绝对路径 ls | sed "s:^:`pwd`/:" # 就是在每行记录的开头加上当前路径 ps: #在所有行之前/后加入某个字符串 sed 's/^/stri ...
- STM32中的几个时钟SysTick、FCLK、SYSCLK、HCLK
STM32参考手册中的时钟树: 关于时钟讲解,在时钟树中都可以看出来:下面是正点原子PPT中的插图,看起来比较清晰. 总结一下: 1. 在STM32中,有五个时钟源,为HSI.HSE.LSI.LSE. ...
- Django模型层之更多操作
Django模型层之更多操作 一 .ORM字段 1.1 常用字段 AutoField int自增列,必须填入参数 primary_key=True.当model中如果没有自增列,则自动会创建一个列名为 ...