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详解】相关推荐

  1. MySQL数据库,从入门到精通:第十四篇——MySQL视图详解

    MySQL数据库,从入门到精通:第十四篇--MySQL视图详解 第 14 篇_视图 1. 常见的数据库对象 2. 视图概述 2. 1 为什么使用视图? 2. 2 视图的理解 3. 创建视图 3. 1 ...

  2. MySQL数据库,从入门到精通:第十二篇——MySQL数据类型详解

    MySQL数据库,从入门到精通:第十二篇--MySQL数据类型详解 第 12 章_MySQL数据类型精讲 1. MySQL中的数据类型 2. 整数类型 2. 1 类型介绍 2. 2 可选属性 2. 2 ...

  3. spring之旅第四篇-注解配置详解

    spring之旅第四篇-注解配置详解 一.引言 最近因为找工作,导致很长时间没有更新,找工作的时候你会明白浪费的时间后面都是要还的,现在的每一点努力,将来也会给你回报的,但行好事,莫问前程!努力总不会 ...

  4. 【备战春招/秋招系列】美团Java面经总结进阶篇 (附详解答案)

    <!-- MarkdownTOC --> 一 消息队列MQ的套路 1.1 介绍一下消息队列MQ的应用场景/使用消息队列的好处 ①.通过异步处理提高系统性能 ②.降低系统耦合性 1.2 那么 ...

  5. Struts2拦截器的使用 (详解)

    Struts2拦截器的使用 (详解) 如何使用struts2拦截器,或者自定义拦截器.特别注意,在使用拦截器的时候,在Action里面必须最后一定要引用struts2自带的拦截器缺省堆栈default ...

  6. 【备战春招/秋招系列】美团Java面经总结终结篇 (附详解答案)

    该文已加入开源项目:JavaGuide(一份涵盖大部分Java程序员所需要掌握的核心知识的文档类项目,Star 数接近 14 k).地址:https://github.com/Snailclimb.. ...

  7. 【备战春招/秋招系列】美团Java面经总结终结篇 (附详解答案) 1

    该文已加入开源项目:JavaGuide(一份涵盖大部分Java程序员所需要掌握的核心知识的文档类项目,Star 数接近 14 k).地址:https://github.com/Snailclimb/J ...

  8. 离线强化学习(Offline RL)系列3: (算法篇) AWAC算法详解与实现

    [更新记录] 论文信息:AWAC: Accelerating Online Reinforcement Learning with Offline Datasets [Code] 本文由UC Berk ...

  9. 入木三分学网络第一篇--VRRP协议详解-----(1)

    原帖:http://blog.chinaunix.net/uid-11654074-id-2857384.html 目录 入木三分学网络第一篇--VRRP协议详解 1. VRRP产生背景及应用环境 1 ...

  10. k8s教程(Volume篇)-PVC详解

    文章目录 01 引言 02 PVC详解 2.1 参数配置 2.1.1 资源请求(Resources) 2.1.2 访问模式 (Access Modes) 2.1.3 存储卷模式(Volume Mode ...

最新文章

  1. 《深度探索C++对象模型》--3 Data语意学
  2. Red Hat Enterprise Linux(RHEL)中yum的repo文件详解
  3. Java IO: 其他字节流(上)
  4. Java 8编写自定义收集器简介
  5. system.argumentnullexception值不能为null_MySQL NULL 值如何处理?
  6. 快速学习 rollup 打包
  7. LVS负载均衡集群服务搭建详解(一)
  8. 微信公号“架构师之路”学习笔记(六)-互联网一致性架构设计(session一致性,主从一致性,双主一致性,缓存一致性,冗余一致性,消息时序一致性,分布式事务一致性,数据扣减一致性等)
  9. python飞机大战类_500行代码,教你用python写个微信飞机大战
  10. 2022见证中国崛起从Python绘制中国地图开始:使用pyecharts最新版本绘制中国地图实例详解,个性化地图定制及常用参数解析
  11. 国产谷歌地球,地形分析秒杀同款地图软件
  12. 2019111 控制台上实现极乐净土(有图有背景音乐)
  13. 服务器出现硬盘坏道怎么办,硬盘坏道修复全攻略
  14. RFM、PSM、波士顿矩阵模型简介
  15. 计算机组成原理输入输出系统——DMA方式
  16. django LookUp
  17. 产品读书《简约至上 : 交互式设计四策略》
  18. 靖哥哥教你一步一步搭建redis集群环境
  19. java 表格 列删除_Java 删除Excel表格中的空白行或列
  20. 微信小程序的事件处理,吊打面试官系列!

热门文章

  1. Java Switch语句及性能剖析(转载补充)
  2. 拇指接龙游戏从WIN32向Xcode 4.5移植过程问题记录
  3. CentOS GRUB引导错误无法进入系统解决办法
  4. check_http检查http服务
  5. 你所能用到的数据结构之番外篇---逆袭的面向对象(一)
  6. 常见NetBackup通讯问题及排错一般步骤
  7. Linux 修复严重的内核代码执行漏洞
  8. 欧盟网络安全局发布《供应链攻击威胁全景图》报告(下)
  9. LeetCode笔记:39. Combination Sum
  10. 如果外卖APP想窃听我,有几个骚操作?