OGNL表示式使用和值栈
另外值得参考博客:http://blog.csdn.net/resigshy/article/details/7560573
OGNL是Object Graphic Navigation Language(对象图导航语言)的缩写,它是一个开源项目。Struts2框架使用OGNL作为默认的表达式语言,是一种比EL强大很多倍的语言。
OGNL 提供五大类功能
1、支持对象方法调用,如xxx.doSomeSpecial();
2、支持类静态的方法调用和值访问
3、访问OGNL上下文(OGNL context)和ActionContext;(重点:操作ValueStack值栈 )
4、支持赋值操作和表达式串联
5、操作集合对象。
使用OGNL访问对象方法和静态方法
OGNL在jsp结合struts2标签库使用,<s:property value="ognl表达式" /> 执行 ognl表达式
<!--调用实例方法:对象.方法()-->
<s:property value="'hello,world'.length()"/>
<!--调用静态方法:@[类全名(包括包路径)]@[方法名]-->
<!--使用静态方法调用必须设置struts.ognl.allowStaticMethodAccess=true-->
<s:property value="@java.lang.String@format('您好,%s','小明')"/>
访问OGNL上下文(OGNL context)和ActionContext

什么是值栈ValueStack ?
ValueStack是struts2提供一个接口,实现类OgnlValueStack----值栈对象(OGNL是从值栈中获取数据的 ),每个Action实例都有一个ValueStack对象(一个请求对应一个ValueStack对象 ),在其中保存当前Action对象和其他相关对象(值栈中是有Action引用的),Struts框架把ValueStack对象保存在名为“struts.valueStack”的请求属性中(值栈对象是request一个属性)
值栈的内部结构?
值栈由两部分组成
ObjectStack:Struts把动作和相关对象压入ObjectStack中--List
ContextMap:Struts 把各种各样的映射关系(一些Map类型的对象)压入ContextMap中
Struts会把下面这些映射压入ContextMap中
parameters:该Map中包含当前请求的请求参数
request:该Map中包含当前request对象中的所有属性
session:该Map中包含当前session对象中的所有属性
application:该Map中包含当前application对象中的所有属性
attr:该Map按如下顺序来检索某个属性:request,session,application
ValueStack中存在root属性(CompoundRoot) 、context属性(OgnlContext ),CompoundRoot就是ArrayList,OgnlContext就是 Map
context对应Map引入root对象 ,context中还存在request、session、application、attr、parameters对象引用
OGNL表达式,访问root中数据时不需要#,访问request、session、application、attr、parameters对象数据必须写#
操作值栈默认指操作 root 元素
值栈对象的创建,ValueStack和ActionContext是什么关系 ?
//Struts2源码
ActionContext ctx = ActionContext.getContext();
if (ctx != null){
stack = ctx.getValueStack();
}
每一次请求时,都会创建valueStack,在ActionContext中持有了valueStack的引用。
如何获得值栈对象
获得值栈对象有两种方法
ValueStack valueStack = (ValueStack) ServletActionContext.getRequest().getAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY);
ValueStack valueStack2 = ActionContext.getContext().getValueStack();
向值栈保存数据(主要针对root)
//两种方式
//将数据保存root的索引0位置,放置到第一个元素ArrayList.add(0,element);
valueStack.push("tom");
//在值栈创建参数map,将数据保存到map中
valueStack.set("username", "tom");
在jsp中可以通过<s:debug />查看值栈的内容
在JSP中获取值栈的数据
访问root中数据不需要#,访问其它对象数据加#
通过下标获取root中对象
<s:property value="[0].top"/> <!--取值栈顶对象-->
直接在root中查找对象属性(自上而下自动查找)
valueStack:<s:property value="username"/>
在OgnlContext中获取数据
request:<s:property value="#request.username"/>
session:<s:property value="#session.username"/>
application:<s:property value="#application.username"/>
attr:<s:property value="#attr.username"/>
parameters:<s:property value="#parameters.cid[0]"/>
值栈在开发中应用
主流应用:值栈解决Action向JSP传递数据的问题
Action向JSP传递数据处理结果,结果数据有两种形式
1)消息String类型数据
this.addFieldError("msg", "字段错误信息");
this.addActionError("Action全局错误信息");
this.addActionMessage("Action的消息信息");
//fieldError针对某一个字段错误信息(常用于表单校验)、actionError(普通错误信息,不针对某一个字段登陆失败)、actionMessage通用消息
在jsp中使用 struts2提供标签 显示消息信息
<s:fielderror fieldName="msg"/>
<s:actionerror/>
<s:actionmessage/>
2)数据(复杂类型数据)
使用值栈:valueStack.push(products);
哪些数据默认会放入到值栈?
1)每次请求,访问Action对象会被压入值栈 -----DefaultActionInvocation的init方法stack.push(action);
Action如果想传递数据给JSP,只要将数据保存到成员变量,并且提供get方法就可以了
2)ModelDriven接口有一个单独拦截器
<interceptor name="modelDriven" class="com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor"/>
在拦截器中,将model对象压入了值栈stack.push(model),如果Action实现了ModelDriven接口,值栈默认栈顶对象就是model对象
为什么EL也能访问值栈中的数据
struts2框架中所使用的request对象,是增强后的request对象,增强后的request,会首先在request域范围查找,如果查找不到,会在valueStack中查找。
StrutsPreparedAndExecuteFilter的doFilter代码中request=prepare.wrapRequest(request),对Request对象进行了包装,重写了request的getAttribute方法
//源码
Object attribute = super.getAttribute(s);
if (attribute == null) {
attribute = stack.findValue(s);//访问request范围的数据时,如果数据找不到,去值栈中找
}
OGNL表达式常见使用(#,%,$符号使用)
1)#的使用
用法一:#代表ActionContext.getContext()上下文
<s:property value="#request.name" />-----> ActionContext().getContext().getRequest().get("name");
用法二:不写#默认在值栈中root中进行查找
<s:property value="name" />
查询元素时,从root的栈顶元素开始查找,如果访问指定栈中元素
<s:property value="[1].name" /><!--访问栈中第二个元素name属性-->
<s:property value="[1].top" /><!--访问第二个元素对象(会包含Struts2本身的一些属性值,如{username=tom, com.opensymphony.xwork2.util.OgnlValueStack.MAP_IDENTIFIER_KEY=})-->
用法三:进行投影映射(结合复杂对象遍历)
1)集合的投影(只输出部分属性)
<h1>遍历集合只要name属性</h1>
<s:iterator value="products.{name}" var="pname">
<s:property value="#pname"/>
</s:iterator>
2)遍历时,对数据设置条件
<h1>遍历集合只要price大于1500商品</h1>
<s:iterator value="products.{?#this.price>1500}" var="product">
<s:property value="#product.name"/> --- <s:property value="#product.price"/>
</s:iterator>
3)综合
<h1>只显示价格大于1500 商品名称</h1>
<s:iterator value="products.{?#this.price>1500}.{name}" var="pname">
<s:property value="#pname"/>
</s:iterator>
用法四:使用#构造map集合
<h1>使用#构造map集合 遍历</h1>
<s:iterator value="#{'name':'aaa','age':'20', 'hobby':'sport' }" var="entry">
key : <s:property value="#entry.key"/> , value: <s:property value="#entry.value"/> <br/>
</s:iterator>
2) %的使用
用法一:结合struts2表单表单使用,通过%通知struts,%{}中内容是一个OGNL表达式,进行解析
<s:textfield name="username" value="%{#request.username}"/>
用法二: 设置ognl表达式不解析 %{'ognl表达式'}
<s:property value="%{'#request.username'}"/>
3)$的使用
用法一:用于在国际化资源文件中,引用OGNL表达式
在properties文件 msg=欢迎您, ${#request.username}
在页面
<!--自动将值栈的username 结合国际化配置信息显示-->
<s:i18n name="messages">
<s:text name="msg"></s:text>
</s:i18n>
用法二:在Struts2配置文件中,引用OGNL表达式
<!-- 在Action 提供 getContentType方法 -->
<param name="contentType">${contentType}</param>
${contentType}读取值栈中contentType数据,在Action提供getContentType方法,因为Action对象会被压入值栈,
结论:#使用ognl表达式获取数据,%控制ognl表达式是否解析,$用于配置文件获取值栈的数据
ognl操作集合(了解)
<s:property value="products[0].name"/> 访问集合第一个元素name属性
<s:property value="map['name']"/> 访问map中key为name的值
{} 直接构造List 元素、 #{} 直接构造 Map元素
<s:iterator value="{'aaa','bbb'}" var="s">
<s:property value="#s"/>
</s:iterator>
<s:iterator value="#{'ccc':'111','ddd':'222' }" var="entry">
<s:property value="#entry.key"/>
</s:iterator>
OGNL表示式使用和值栈的更多相关文章
- Java中的值栈
OGNL表示式使用 和 值栈 OGNL是Object Graphic Navigation Language(对象图导航语言)的缩写,它是一个开源项目. Struts2框架使用OGNL作为默认的表达式 ...
- 值栈和OGNL 之 7.1 值栈
7.1 值栈 7.1.1 值栈是什么 简单的说:值栈是对应每一个请求对象的轻量级的内存数据中心. Struts2中一个很激动人心的特性就是引入了值栈,在这里统一管理着数据,供Action.Resu ...
- struts2 ognl表达式访问值栈
1:简单的说,值栈是对应每一个请求对象的轻量级的数据存储中心,在这里统一管理着数据,供Action.Result.Interceptor等Struts2的其他部分使用,这样数据被集中管理起来而不凌乱. ...
- Struts2的值栈和OGNL牛逼啊
Struts2的值栈和OGNL牛逼啊 一 值栈简介: 值栈是对应每个请求对象的一套内存数据的封装,Struts2会给每个请求创建一个新的值栈,值栈能够线程安全的为每个请求提供公共的数据存取服务. 二 ...
- 【struts2】值栈(前篇)
1 值栈是什么? 简单的说:值栈是对应每一个请求对象的轻量级的内存数据中心. Struts2中一个很激动人心的特性就是引入了值栈,在这里统一管理着数据,供Action.Result.Intercept ...
- ValueStack值栈和ActionContext
Struts2在OGNL之上提供的最大附加特性就是支持值栈(ValueStack),在OGNL上下文中只能有一个根对象,Struts2的值栈则允许存在许多虚拟对象. 一:值栈(ValueStack) ...
- Struts2_day03--课程安排_OGNL概述入门_什么是值栈_获取值栈对象_值栈内部结构
Struts2_day03 上节内容 今天内容 OGNL概述 OGNL入门案例 什么是值栈 获取值栈对象 值栈内部结构 向值栈放数据 向值栈放对象 向值栈放list集合 从值栈获取数据 获取字符串 获 ...
- Struts2值栈
一.前言 很多事儿啊,就是“成也萧何败也萧何”,细想一些事儿心中有感,当然,感慨和本文毛关系都没有~想起之前有篇Struts2中值栈的博客还未完工,就着心中的波澜,狂咽一把~ 二.正文 博文基于:st ...
- valueStack(值栈)
值栈 值栈(ValueStack)就是 OGNL 表达式存取数据的地方.在一个值栈中,封装了一次请求所需要的所有数据. 在使用 Struts2 的项目中,Struts2 会为每个请求创建一个新的值栈, ...
随机推荐
- linux学习之一些琐碎知识点
一.python 问:django中project和app之间到底有什么不同? 答:他们的区别就是一个是配置,另一个是代码. 一个project包含很多个django app以及对它们的配置.技术上, ...
- Qt 子窗体嵌入父窗体
1.创建个子窗体QDialog.在子窗体构造函数添加 Dialog::Dialog(QWidget *parent) : QDialog(parent), ui(new Ui::Dialog) { u ...
- ACM/ICPC 之 BFS(离线)+康拓展开 (HDU1430-魔板)
魔板问题,一道经典的康拓展开+BFS问题,为了实现方便,我用string类来表示字符串,此前很少用string类(因为不够高效,而且相对来说我对char数组的相关函数比较熟),所以在这里也发现了很多容 ...
- 1.openstack之mitaka搭建基本配置
介绍:本次案列为基本的三节点部署 注:搭建所需要的包可以联系QQ:22102107获取 一:网络: 1.管理网络:192.168.11.0/24 2.数据网络:1.1.1.0/24 注:每个节点两个网 ...
- Js 旋转木马 轮播
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Gson简要使用笔记
最近在做一个java web service项目,需要用到jason,本人对java不是特别精通,于是开始搜索一些java平台的json类库. 发现了google的gson,因为之前对于protoco ...
- 51nod 1099 任务执行顺序 (贪心算法)
题目:传送门. 题意:中文题. 题解:r[i]-o[i]值大的先进行.反证法:如果大的后进行,会导致空间增大,所以一定大的是先进行. #include <iostream> #includ ...
- 当对服务器端返回的极光推送数据请求时,AFN 的 GET 请求失败如何解决
代码段 控制台 只需在 manager 那里添加一行代码即可 //传入json格式数据,不写则普通post manager.requestSerializer = [AFJSONReque ...
- springmvc注解配置
<?xml version="1.0" encoding="UTF-8" ?> <beans xmlns="http://www.s ...
- Java -- 找不到或无法加载主类
原文:http://wenku.baidu.com/link?url=5nS1GEaePn-hmtAg6xXdJvtt9Z89JQsakhqSv8fambaJY2t9nKPtf3hXFpjW-BtD9 ...