Struts2第九篇【OGNL、valueStack详解】
tags: Struts2
什么是OGNL表达式?
OGNL是Object Graphic Navigation Language 是操作对象属性的开源表达式。 Struts2框架使用OGNL作为默认的表达式语言。
为什么我们学习OGNL
在学习JSP的时候,我们已经学习过了EL表达式。EL表达式用起来也十分简单...我们在Struts2框架中也是可以使用EL表达式的...那么OGNL表达式好在哪里呢??
- 支持对象方法调用,如xxx.doSomeSpecial()
- 支持类静态的方法调用和值访问,表达式的格式【例如:"@@floor(10.9)"就是调用Math.floor()的方法了】
- 支持赋值操作和表达式串联【这个其实EL表达式也能做】
- 访问OGNL上下文(OGNL context)和ActionContext
- 操作集合对象【EL只能遍历集合,OGNL可以创建集合】
OGNL是Struts2的默认表达式语言,OGNL是配搭Strut2的标签使用的..我们学习了OGNL表达式,就可以更好地理解Struts2标签的运行以及Struts2内部的存储结构.
valueStack对象
在讲解OGNL表达式之前,我们先来看看valueStack对象...valueStack是Struts2数据存储的核心...我们首先要知道数据是怎么存的,存到哪里,然后才讲解OGNL表达式是怎么取出数据的。
valueStack也被称作值栈对象..
- 当用户访问Action,都会创建一个Action对象,ActionContext对象、valueStack对象..
- Struts2把Action对象放进valueStack对象之中。
- 将valueStack放进request域中,传入JSP页面(key: struts.valueStack)
- JSP页面就可以使用OGNL表达式获取值栈中的数据了!
获取valueStack对象
- 在Action中我们可以手动获取值栈对象,有两种方式获取:
//获取值栈对象的2种方式private void getVs() {// 获取值栈对象,方式1:HttpServletRequest request = ServletActionContext.getRequest();ValueStack vs1 = (ValueStack) request.getAttribute("struts.valueStack");// 获取值栈对象,方式2: ActionContext ac = ActionContext.getContext();ValueStack vs2 = ac.getValueStack();System.out.println(vs1 == vs2);//true}复制代码
valueStack内部存储结构
上面已经说了,用户访问Action时,会创建Action对象,valueStack对象。Struts2内部会将Action对象存到valueStack对象之中...那么valueStack的存储结构是什么样的呢???我们来看看
CompoundRoot
Action对象和Action的成员属性等值都是存到CompoundRoot下的.该CompoundRoot继承着ArrayList,因此它是List结构的
public class CompoundRoot extends ArrayList {}复制代码
OgnlContext
OgnlContext对象存储着相关的域对象:request、response、session等数据,实现Map集合,是Map结构..
为了让request、response等域对象可以存储多个值,值也是使用Map结构...
public class OgnlContext implements Map {}复制代码
小总结
CompoundRoot保存着这样的数据:
- Action对象以及Action对象的成员属性数据
- 使用ValueStack对象.push()进去的数据
- 使用ValueStack对象.set()进去的数据
- 其他代理对象的数据
OgnlContext保存着这样的数据:
- 维护了CompoundRoot中所有的数据
- request、response等域对象所有的数据
OGNL表达式取值
- Struts2会将valueStack对象封装进request对象域中,传入JSP页面。
- valueStack存储着OgnlContext对象。
- OgnlContext对象维护了CompoundRoot对象的数据
- CompoundRoot存储着Action等数据
也就是说通过OgnlContext对象可以获取大部分我们需要的数据了。
那么OGNL表达式是怎么取出OgnlContext对象中数据的呢??下面我们通过硬编码的方式来讲解:
/*** 1. Ognl表达式语言语言取值,取非根元素的值,必须用#号* @throws Exception*/@Testpublic void testOgnl() throws Exception {// 创建一个Ognl上下文对象OgnlContext context = new OgnlContext();// 放入数据User user = new User();user.setId(100);user.setName("Jack");// 【往非根元素放入数据, 取值的时候表达式要用"#"】context.put("user", user);// 获取数据(map)// 先构建一个Ognl表达式, 再解析表达式Object ognl = Ognl.parseExpression("#user.name");Object value = Ognl.getValue(ognl, context, context.getRoot());System.out.println(value);}/*** 2. Ognl表达式语言语言取值,取根元素的值,不用带#号* @throws Exception*/@Testpublic void testOgn2() throws Exception {// 创建一个Ognl上下文对象OgnlContext context = new OgnlContext();// 放入数据User user = new User();user.setId(100);user.setName("Jack");// 【往根元素放入数据】context.setRoot(user);// 获取数据(map)// 先构建一个Ognl表达式, 再解析表达式Object ognl = Ognl.parseExpression("address.province");Object value = Ognl.getValue(ognl, context, context.getRoot());System.out.println(value);}复制代码
也就是说,JSP页面中取出数据的时候,它会先构建一个OGNL表达式,再解析表达式
- 如果是CompoundRoot类的数据,表达式不需要带#号
- 如果不是CompoundRoot类的数据,表达式需要带#号
例子:
<!-- 页面: 必须要拿到ValueStack --><br/>1. 取根元素的值<br/><s:property value="user.id"/> <s:property value="user.name"/> <s:property value="user.address"/> <s:property value="user.address.city"/> <s:property value="user.address.province"/> <br/>2. 取非根元素的值<br/><s:property value="#request.cn"/><s:property value="#session.Session_data"/><s:property value="#application.Application_data"/> <br/><!-- 自动找request/session/application,找到后立刻返回 --><s:property value="#request_data"/><s:property value="#attr.Session_data"/><s:property value="#attr.Application_data"/> <br/><!-- 获取请求的参数数据 --><s:property value="#parameters.userName"/><!-- struts的调试标签:可以观测值栈数据 --><s:debug></s:debug>复制代码
OGNL对静态方法的调用
/*** 3.Ognl对 静态方法调用的支持* @throws Exception*/@Testpublic void testOgn3() throws Exception {// 创建一个Ognl上下文对象OgnlContext context = new OgnlContext();// Ognl表单式语言,调用类的静态方法//Object ognl = Ognl.parseExpression("@Math@floor(10.9)");// 由于Math类在开发中比较常用,所以也可以这样写Object ognl = Ognl.parseExpression("@@floor(10.9)");Object value = Ognl.getValue(ognl, context, context.getRoot());System.out.println(value);}
复制代码
OGNL创建集合
<br/>一、.构建 list集合</br><s:iterator var="str" value="{'a','b'}"><s:property value="#str"/></s:iterator><br/>一、.构建 map集合</br><s:iterator var="en" value="#{'cn':'China','usa':'America'}"><s:property value="#en.key"/><s:property value="#en.value"/> <br/></s:iterator>复制代码
构建Map集合的时候,需要使用#号
#OGNL 几个特殊的符号#
#获取非根元素值 、 动态都建map集合 $ 在配置文件取值 % 提供一个ognl表达式运行环境
<body><br/>获取request域数据<br/><!-- property 标签是对象类型的标签,默认支持ognl表达式, 会从根元素去China名称对应的值 --><s:property value="China"/> <br/><!-- 如果直接赋值,需要用单引号 --><s:property value="'China'"/> <br/><s:property value="%{#request.cn}"/> <br/><!-- 值类型的标签,value值默认就是值类型,不支持ognl表达式 -->国家:<s:textfield name="txtCountry" value="%{#request.cn}"></s:textfield></body>
复制代码
如果您觉得这篇文章帮助到了您,可以给作者一点鼓励
Struts2第九篇【OGNL、valueStack详解】相关推荐
- MySQL数据库,从入门到精通:第十四篇——MySQL视图详解
MySQL数据库,从入门到精通:第十四篇--MySQL视图详解 第 14 篇_视图 1. 常见的数据库对象 2. 视图概述 2. 1 为什么使用视图? 2. 2 视图的理解 3. 创建视图 3. 1 ...
- MySQL数据库,从入门到精通:第十二篇——MySQL数据类型详解
MySQL数据库,从入门到精通:第十二篇--MySQL数据类型详解 第 12 章_MySQL数据类型精讲 1. MySQL中的数据类型 2. 整数类型 2. 1 类型介绍 2. 2 可选属性 2. 2 ...
- spring之旅第四篇-注解配置详解
spring之旅第四篇-注解配置详解 一.引言 最近因为找工作,导致很长时间没有更新,找工作的时候你会明白浪费的时间后面都是要还的,现在的每一点努力,将来也会给你回报的,但行好事,莫问前程!努力总不会 ...
- 【备战春招/秋招系列】美团Java面经总结进阶篇 (附详解答案)
<!-- MarkdownTOC --> 一 消息队列MQ的套路 1.1 介绍一下消息队列MQ的应用场景/使用消息队列的好处 ①.通过异步处理提高系统性能 ②.降低系统耦合性 1.2 那么 ...
- Struts2拦截器的使用 (详解)
Struts2拦截器的使用 (详解) 如何使用struts2拦截器,或者自定义拦截器.特别注意,在使用拦截器的时候,在Action里面必须最后一定要引用struts2自带的拦截器缺省堆栈default ...
- 【备战春招/秋招系列】美团Java面经总结终结篇 (附详解答案)
该文已加入开源项目:JavaGuide(一份涵盖大部分Java程序员所需要掌握的核心知识的文档类项目,Star 数接近 14 k).地址:https://github.com/Snailclimb.. ...
- 【备战春招/秋招系列】美团Java面经总结终结篇 (附详解答案) 1
该文已加入开源项目:JavaGuide(一份涵盖大部分Java程序员所需要掌握的核心知识的文档类项目,Star 数接近 14 k).地址:https://github.com/Snailclimb/J ...
- 离线强化学习(Offline RL)系列3: (算法篇) AWAC算法详解与实现
[更新记录] 论文信息:AWAC: Accelerating Online Reinforcement Learning with Offline Datasets [Code] 本文由UC Berk ...
- 入木三分学网络第一篇--VRRP协议详解-----(1)
原帖:http://blog.chinaunix.net/uid-11654074-id-2857384.html 目录 入木三分学网络第一篇--VRRP协议详解 1. VRRP产生背景及应用环境 1 ...
- k8s教程(Volume篇)-PVC详解
文章目录 01 引言 02 PVC详解 2.1 参数配置 2.1.1 资源请求(Resources) 2.1.2 访问模式 (Access Modes) 2.1.3 存储卷模式(Volume Mode ...
最新文章
- 《深度探索C++对象模型》--3 Data语意学
- Red Hat Enterprise Linux(RHEL)中yum的repo文件详解
- Java IO: 其他字节流(上)
- Java 8编写自定义收集器简介
- system.argumentnullexception值不能为null_MySQL NULL 值如何处理?
- 快速学习 rollup 打包
- LVS负载均衡集群服务搭建详解(一)
- 微信公号“架构师之路”学习笔记(六)-互联网一致性架构设计(session一致性,主从一致性,双主一致性,缓存一致性,冗余一致性,消息时序一致性,分布式事务一致性,数据扣减一致性等)
- python飞机大战类_500行代码,教你用python写个微信飞机大战
- 2022见证中国崛起从Python绘制中国地图开始:使用pyecharts最新版本绘制中国地图实例详解,个性化地图定制及常用参数解析
- 国产谷歌地球,地形分析秒杀同款地图软件
- 2019111 控制台上实现极乐净土(有图有背景音乐)
- 服务器出现硬盘坏道怎么办,硬盘坏道修复全攻略
- RFM、PSM、波士顿矩阵模型简介
- 计算机组成原理输入输出系统——DMA方式
- django LookUp
- 产品读书《简约至上 : 交互式设计四策略》
- 靖哥哥教你一步一步搭建redis集群环境
- java 表格 列删除_Java 删除Excel表格中的空白行或列
- 微信小程序的事件处理,吊打面试官系列!