Struts2【OGNL、valueStack】就是这么简单

小编 2026-06-29 阅读:1774 评论:0
什么是OGNL表达式?OGNL是Object Graphic Navigation Langua...

什么是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表达式获取值栈中的数据了

Struts2【OGNL、valueStack】就是这么简单

获取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的存储结构是什么样的呢???我们来看看

Struts2【OGNL、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 {}

小总结

Struts2【OGNL、valueStack】就是这么简单

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     */    @Test    public 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     */    @Test    public 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类的数据,表达式需要带#号

Struts2【OGNL、valueStack】就是这么简单

例子:

    <!-- 页面: 必须要拿到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     */    @Test    public 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>

如果文章有错的地方欢迎指正,大家互相交流。习惯在微信看技术文章,想要获取更多的Java资源的同学,可以关注微信公众号:Java3y

更多的文章可往:文章的目录导航
版权声明

本文仅代表作者观点,不代表百度立场。
本文系作者授权百度百家发表,未经许可,不得转载。

热门文章
  • 机房智能化温湿度解决方式之POE供电以太网温湿度传感器

    机房智能化温湿度解决方式之POE供电以太网温湿度传感器
    机房智能化温湿度解决方式之POE供电以太网温湿度传感器 北京盈创力和电子科技有限公司 智能型TCP网口温湿度记录仪 北京IP网络温湿度记录仪厂家,北京盈创力和 北京智能型TCP网口温湿度记录仪IP网络温湿度记录仪是一种新型的基于TCP/IP协议双绞线以太网标准温湿度采集模块,利用它可以实现现场温度值、相对湿度值的采集,同时利用其自身的RJ45通信接口可以方便地和机房监控主机或交换机集线器进行联网。 工作于-40℃~85℃工业级带...
  • Sequential Monte Carlo Methods (SMC) 序列蒙特卡洛/粒子滤波/Bootstrap Filtering

    Sequential Monte Carlo Methods (SMC) 序列蒙特卡洛/粒子滤波/Bootstrap Filtering
    Problem Statement 我们考虑一个具有马尔可夫性质、非线性、非高斯的状态空间模型(State Space Model):对于一个时间序列上的观测结果{yt,t∈N}\\{ y_t , t \\in N \\}{yt​,t∈N},我们认为每个观测结果yty_tyt​的生成依赖于一个无法直接观察的隐变量xt∈{xt,t∈N}x_t \\in \\{x_t , t \\in N \\}xt​∈{xt​,t∈N},即:p(...
  • HTTP状态保持的原理

    HTTP状态保持的原理
    a)在用户登录之后,浏览器返回响应的时候会在响应中添加上cookieb)浏览器接收到cookie之后会自动保存c)当用户再次请求同一服务器中的其他网页的时候,浏览器会自动带上之前保存的cookied)服务接收到请求之后可以请 request 对象中取到cookie 判断当前用户是否登录  Http是无状态的,就是连接时数据互通,关闭后...
  • CSRF的原理和防范措施

    CSRF的原理和防范措施
    a)攻击原理:i.用户C访问正常网站A时进行登录,浏览器保存A的cookieii.用户C再访问攻击网站B,网站B上有某个隐藏的链接或者图片标签会自动请求网站A的URL地址,例如表单提交,传指定的参数iii.而攻击网站B在访问网站A的时候,浏览器会自动带上网站A的cookieiv.所以网站A在接收到请求之后可判断当前用户是登录状态,所以...
  • Hive 系统函数及示例

    Hive 系统函数及示例
    查看所有系统函数 show functions; 函数分类 内置函数【系统函数】 数学函数: floor、round、ceil、cos、log2等 字符串函数: length、reverse、trim、lower、get_json_object、repeat等 收集函数: size 转换函数: cast 日期函数: year、month、datediff、date、date_add等 条件函数: coalesce、case…w...
标签列表