OGNL 理解

h1. 一个例子
请看下面的需求,假设有如下用户对象模型:

Java代码
  1. public   interface  User {  
  2.     public  String getName();  
  3.     public  Date getRegisterDate();  
  4.     public  Customer getCustomer();  
  5. }  
  6. public   interface  Customer {  
  7.     public  String getId();  
  8.     public  String getName();  
  9.     public   boolean  isVip();  
  10. }  
  11. public   interface  EntCustomer  extends  Customer {  
  12.     public  String getTrustId();  // 组织机构代码证号   
  13. }  
public interface User {    
public String getName();    
public Date getRegisterDate();    
public Customer getCustomer();
}
public interface Customer {
public String getId();    
public String getName();    
public boolean isVip();
}
public interface EntCustomer extends Customer {    
public String getTrustId(); // 组织机构代码证号
}


对于给定的用户jack,且该用户所属客户是企业客户,那么我们如何获取该用户的姓名?如何获取用户所属客户的名称?如何判断该用户所属客户是否是VIP客户?如何取jack所属企业的组织机构代码证号?

 

* 采用java代码的方式,我们可以用如下的API调用得到所需信息:

Java代码
  1. jack.getName();  
  2. jack.getCustomer().getName();  
  3. jack.getCustomer().isVip();  
  4. ((EntCustomer)jack.getCustomer()).getTrustId();  
jack.getName();jack.getCustomer().getName();jack.getCustomer().isVip();((EntCustomer)jack.getCustomer()).getTrustId();

 

* 但我们现在在讲述OGNL,因此通过采用OGNL,我们可以用如下方式取得我们所需要的信息:

Java代码
  1. jack.name  
  2. jack.customer.name  
  3. jack.vip  
  4. jack.customer.trustId  
jack.namejack.customer.namejack.vipjack.customer.trustId


由此我们可以看到OGNL的表达方式与java表达方式有以下几点不同:
** 不需关注对象类型,不需进行类型转换
** 表达方式更简短和直观

 

OGNL表达式最大的优点就是:*简单* 和 *直观*,你不这样认为吗? 如果你觉得上面的表达式还不够简单和直观,那我们再来看:

Java代码
  1. name  
name


这也是一个OGNL表达式,也就是取姓名!简单吗?至少足够直观了吧:)

 

h1. 基本概念
我们前面看到了OGNL的一个最简单的例子,事实上OGNL确实很简单,如果能理解上面那个例子的用法,那么我们就掌握了OGNL的80%的用法了。
上面的例子虽然简单,但其中却含有OGNL的两个最基本的概念:*表达式(expression)* 和 *上下文(context)*,我们先看*表达式*。

h3. 表达式
OGNL就是表达式!它能让我们用简洁直观的语法表达我们的想法,如同上面的例子一般。简洁直观就是表达式的最大优点!我们 知道表达式总是有一个结果,也就是说表达式总是会求值出一个结果,这个结果可能是一个字符串(如名称、组织机构代码证号等),或者是一个布尔值(如是否是 VIP客户等),至于这个结果要怎么使用,那就是我们自己来决定的了。

h3. 上下文(context)
表达式的概念,我相信很好理解,但什么是上下文(context)?简单来说上下文就是环境,表达式求值的环境!还是不理解吗?我们来看一个例子:
还是上面最后那个例子:

Java代码
  1. name  
name

细心的你是否会问,这个表达式要取谁的姓名呢?OK,很好!这就是环境,"谁"就存在于环境之中,也就是存在上下文之中。对于不同的环境/上下文,相同的表达式会有不同的结果!而环境/上下文的实质是什么呢?就是一组带名称的对象集合。

引用
思考:表达环境或上下文这个概念的最好的数据结构是什么?

 

h3. OGNL上下文概念详解
我们前面说上下文就是一组名称-对象对的集合,如下图所示就是一个简单的上下文:

Java代码
  1. user ---> User(name: "jack" , ...)  
  2. request ---> HttpServletRequest(header: ...)  
user ---> User(name:"jack", ...)request ---> HttpServletRequest(header: ...)


那么在上面的环境中,我们可以有如下的OGNL表达式:

Java代码
  1. #user.name  // 取用户的姓名   
  2. #user.age // 取用户年龄   
  3. #user.birthday // 取用户生日   
  4. #user.customer.name // 取用户所属客户的名称   
  5. #request.parameters // 取请求参数   
#user.name // 取用户的姓名#user.age // 取用户年龄#user.birthday // 取用户生日#user.customer.name // 取用户所属客户的名称#request.parameters // 取请求参数


请注意上面表达式中的"#user"和"#request"的用法,"#"表示访问环境/上下文中的对象。

 

现在可以很方便地访问环境中的对象了,那么如果你比较懒惰的话(记住:在程序员群体,懒惰是褒义词!),你是否觉得访问用户的姓名,年龄,生日,等等其它属性如果全部要使用"#user"来访问会不会太麻烦了呢?OK,ONGL的设计者早就考虑了这个问题,我们可以指定user为环境中的特权对象,访问该对象可以不需要使用#user的方式,如下所示代码与上面的完全等价,当然,前提是要预先指定user为特权对象 :

Java代码
  1. name  // 取用户的姓名   
  2. age // 取用户年龄   
  3. birthday // 取用户生日   
  4. customer.name // 取用户所属客户的名称   
  5. #request.parameters // 取请求参数   
name // 取用户的姓名age // 取用户年龄birthday // 取用户生日customer.name // 取用户所属客户的名称#request.parameters // 取请求参数

 

我们上面所说的"特权对象"在OGNL中称为"根对象"(root)

h3. 小结
综上所述,理解OGNL表达式的关键是理解其上下文的概念,因为OGNL的上下文概念中引入了"根对象"的概念,所以初学者往往会在这里迷失方向。

 

引用

OGNL的中文全称是对象图导航语言,也就是说OGNL是一门语言,如同java是一门语言一 样。你是否会认为OGNL的作者太夸张了,竟敢把表达式谎称为语言?不,OGNL的语法确实非常简洁,OGNL的代码(我没有说表达式,因为代码是和语法 相匹配的词语)通常不会换行,这意味着我们不可能把OGNL的代码写得很长,但是,这并不意味着OGNL的表达能力很弱。事实上,OGNL的语法设计非常 简洁,但其功能却相当强大,如果你有兴趣,可以深入阅读OGNL参考手册的集合与lambda章节。

 

慢着,事情还未至此结束!struts2对OGNL中的上下文的概念又定义了新的含义,且听我慢慢道来!

h3. struts2中的OGNL上下文
struts2对OGNL上下文的概念又做了进一步扩充,在struts2中,OGNL上下文通常如下所示:

Java代码
  1. |  
  2.                      |--request  
  3.                      |  
  4.                      |--application  
  5.                      |  
  6.        context map---|--OgnlValueStack(root) [ user, action, OgnlUtil, ... ]  
  7.                      |  
  8.                      |--session  
  9.                      |  
  10.                      |--attr  
  11.                      |  
  12.                      |--parameters  


我们可以使用"#requet"访问HttpServletRequest对象, "#session"访问HttpSession对象,但请注意"根对象"是什么?是ValueStack!
那 么ValueStack是什么?值栈。也就是一组对象的堆栈。也就是说,在struts2中,根对象不是我们通常的一个对象,而是一组对象。我们可以 push新的对象到值栈中,也可以弹出值栈的栈顶对象。如上图所示,假设我们将user对象push到值栈中,那么如下的表达式将与之前我们见过的表达式 一样,具有相同的结果:

Java代码
  1. name  // 取用户的姓名   
  2. age // 取用户年龄   
  3. birthday // 取用户生日   
  4. customer.name // 取用户所属客户的名称   
  5. #request.parameters // 取请求参数   
name // 取用户的姓名age // 取用户年龄birthday // 取用户生日customer.name // 取用户所属客户的名称#request.parameters // 取请求参数


也就是说,我们使用name这个表达式 的 时候,ONGL会取"根对象"的name属性,但现在根对象是ValueStack!那么访问ValueStack的name属性意味着什么呢?这意味 着:ValueStack会先查看栈顶元素是否有name属性,如果有就返回该属性值,否则取出栈顶下的元素,继续查看,直到栈底为止。

 

以上就是OGNL表达式的核心概念,你理解了吗?下一步,你需要了进一步了解OGNL的语法,以发掘其更强大的功能!

openpi 入门教程(一)安装、训练、微调与推理 OpenPI是由物理智能团队发布的机器人开源模型和软件包,包含两种主要模型:基于流的扩散视觉-语言-动作模型(VLA)的π₀模型和基于FAST动作标记器的自回归VLA的π₀-FAST模型。这些模型已在超过10,000小时的机器人数据上进行了预训练,并提供了基础模型检查点,支持开箱即用或根据用户数据集进行微调。OpenPI的实验性质意味着它可能不适用于所有平台,但鼓励研究人员和从业者进行创造性实验。运行这些模型需要至少具备NVIDIA GPU,推荐使用RTX 4090或更高规格的显卡。OpenPI支持在Ubu 阅读详情

相关推荐

学习Ultralytics (下载)

Ultralytics由创立,最初是为了简化目标检测模型的开发和应用,专注于构建高效、易用、性能卓越的深度学习框架。其主要产品之一是 YOLO 系列模型,尤其是最新的YOLOv5和YOLOv8,因其在精度、速度和可扩展性方面的出色表现而广受欢迎。

2301_76846375的博客 2864

在hibernate中

在hibernate中,通常配置对象关系映射关系有两种,一种是基于xml的方式,另一种是基于annotation的注解方式,熟话说,萝卜青菜,可有所爱,每个人都有自己喜欢的配置方式,我在试了这两种方式以后,发现使用annotation的方式可以更简介,所以这里就简单记录下通过annotation来配置各种映射关系,在hibernate4以后已经将annotation的jar包集成进来了,如果使用h

u012402926的专栏 406

网站进行企业微信授权登录(附带代码超详细版)

企业微信的扫码登录官方文档 https://work.weixin.qq.com/api/doc/90000/90135/90988 企业微信扫码登录认证流程 上面是官方的图片,看上去比较复杂。因此我用直白简洁的语言梳理下流程。 1、首先在自己的网站上获取到企业微信登录的二维码(二维码怎么获取稍后再说,这里想象下你已经有了一个二维码) 2、你拿着手机扫描二维码,确认登录之后,页面就会自己进行重定向的跳转,跳转的url如何配置下面再讲,但是注意,这个重定向的url可以是内网地址 3、重定向到指

Gzf的博客 1万+

hibernate java.util.date 精度_hibernate中java.util.Date类型映射

在Hibernate中对于java.util.Date类型的映射为: java类型 Hibernate类型 Mysql类型 java.util.Date、java.sql.Date date DATE java.util.Date、java.sql.Time time TIME java.util.Date、java.sql.Timestamp timestamp TIMESTAMP 如果使用ti...

weixin_42367454的博客 209

Web自动化神操作:如何用OpenCV 破解滑块验证码?

验证码作为一种安全机制,可以有效防止暴力破解密码、发帖、灌水、刷票等,大家在做 Web 自动化的时候应该有碰到验证码这个难题,一般我们可以和开发沟通请求他们的帮助:去掉验证码或者设置一个万能验证码,而如果开发不帮忙我们该如何去解决呢? 本篇文章以 Java 语言为例教你怎么破解验证码。 现在大多数网址会采用滑块验证码的方式,下面以腾讯的滑块验证码为例,先来看看破解的效果: 要破解滑块验证码,我们一般采取的思路如下: 获取滑块到背景缺口图的距离 通过 selenium 的 Actio

不喝枸杞的程序员 2035

【BlueZ】编译产物详解:可执行文件/库文件/工具的生成路径与用途

BlueZ二次开发编译产物机制解析 摘要:在BlueZ蓝牙协议栈二次开发中,90%的报错源于对编译产物类型和路径的混淆。本文系统剖析BlueZ的三阶段编译机制:1)配置阶段生成Makefile;2)编译阶段在.libs目录下产生临时库和可执行文件(不可直接运行);3)安装阶段将产物部署到系统标准路径。重点解析守护进程、命令行工具、动态库的核心路径差异,并针对五大高频问题(如临时库运行崩溃、动态库不匹配、系统覆盖等)给出解决方案。

byte轻骑兵的技术小窝 1万+

Mybatis的if判断不要使用boolean类型变量

问题出现场景 定义了一个类,该类中许多变量都定义成了boolean类型,在使用mybatis的if写sql语句时,判断条件中使用了类定义的boolean类型变量,导致结果一直不对 mybatis中if使用介绍 mybatis的if判断里面最好不要使用boolean类型的值。原因:mybatis默认会把boolean变量的空值转为false。所以如果遇见前端传空值,这个字段在mybatis里面永远就...

sinat_34241861的博客 4195

液态神经网络(LNN):打破AI“静态快照”的连续动力学革命---AI大模型系统从零开始0029

MIT研究团队受秀丽隐杆线虫神经系统的启发,开发出革命性的液态神经网络(LNN)。该技术通过连续微分方程建模神经元动态,实现输入响应速度的自适应调节,解决了传统AI模型静态化、高能耗和低解释性的痛点。LNN具有三大突破性优势:仅需少量神经元(如20个)即可完成复杂任务;能处理非均匀时序数据;在自动驾驶、医疗监测等领域展现出卓越的适应性和鲁棒性。这项将生物智能与数学建模完美融合的技术,有望成为下一代AI的核心架构,目前已在无人机导航等场景验证了其高效性,被预测为2026年最具潜力的AI突破方向。

添柴程序猿的专栏 372

mybaits 中 <if test="变量 != ' ' "> 的坑

OGNL对于boolean的定义和JavaScript有点像,即 ' ' == 0 == false 所以在mybatis中做<if test="变量 != ' ' ">校验时 若变量类型是数字类型 就不要做 变量 !=' ' 校验,否则若变量的值是0 ,会导致查询出错! ...

Xhm1064的博客 853

数据挖掘实战-基于情感分析+网络语义分析+LDA主题分析对大唐不夜城用户评论进行文本分析

本研究基于去哪儿网和携程网的1888条大唐不夜城游客评论数据,运用Python进行文本分析。通过情感分析发现游客评价以积极为主(占比约70%),中性占20%,消极占10%。采用ROSTCM6软件进行社会网络语义分析,识别不同情绪下的高频词汇。使用LDA主题模型将评论划分为3个主题(夜景、表演、美食),并分析主题强度随时间变化趋势。实验包含数据采集、预处理、情感分析、语义网络分析和LDA建模等完整流程,为景区管理优化提供数据支持。源代码涵盖爬虫、数据处理和可视化分析的全套实现。

m0_64336780的博客 1万+

使用curl命令出现fatal: unable to access ‘https://github.com/nvm-sh/nvm.git/‘: Encountered end of file的解决方案

本文主要介绍了使用curl命令出现fatal: unable to access ‘https://github.com/nvm-sh/nvm.git/’: Encountered end of file的解决方案,希望能对使用curl命令的同学们有所帮助。 文章目录 1. 问题描述 2. 解决方案

weixin_43178406的博客 1万+

http请求详细分析

一.http请求 ①是请求方法,GET和POST是最常见的HTTP方法,除此以外还包括DELETE、HEAD、OPTIONS、PUT、TRACE。不过,当前的大多数浏览器只支持GET和POST,Spring 3.0提供了一个HiddenHttpMethodFilter,允许你通过“_method”的表单参数指定这些特殊的HTTP方法(实际上还是通过POST提交表单)。服务端配置了H...

bangfox0730的博客 1573

《DeepJIT: An End-To-End Deep Learning Framework for Just-In-Time Defect Prediction》论文笔记

软件工程任务:即时缺陷预测(涉及SE+AI知识)

weixin_43646592的博客 701

如何OGNL理解

OGNL全名Object Graph Navigation Language,可认为是更完美EL表达式。   它可以真正意义上代替个传统jsp服务器脚本()。本文不阐述OGNL的优势,志在为帮助大家理解并学习OGNL。   以下是struts2中的OGNL。 OGNL的表达式的资料确实不少,但几乎都是同一个版本,并且笔者真的有怀疑此版本的作者在一些关键问题上要么就是自己也没弄清楚,要么就

博观而约取,厚积而薄发 417

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

对struts2的OGNL的理解

OGNL:Object-Graph Navigation Language.对象图形化导航语言 OGNL是集成进struts2框架中比較强大的技术有助于传输数据和类型转换,OGNL由表达式语言和类型装换器组成。 表达式语言: 我们已经在jsp表单input名和jsp标签使用该语言了.他用来绑定java端的数据属性和基于字符串的 视图层表示.表达式语言甚至能够进行方法调用,目的就在于...

weixin_34129145的博客 78

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

OGNL的理解

1. 什么是OGNL OGNL是Object-Graph Navigation Language的缩写,它是一种功能强大的表达式语言,是一个第三方开源项目。 OGNL本身是与Struts2没有任何关系的。但Struts框架使用了OGNL用于进行表达式的计算工作。Struts2通过使用OGNL简单一致的表达式语法,可以存取对象的任意属性,调用对象的方法,遍历整个对象的结构图,实现字段类型转化等...

I_AM_good_boy的博客 1010

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

Ognl的理解

OGNL   OGNL全称Object-Graph Navigation Language,是一种用于读取和设置java对象属性的描述语言。WebOGNL是一种构建以servlet为基础的组件化应用的web表现层框架,它的模板语言建立在OGNL表达式的基础上,具有别的web层框架不能匹敌的适应性。OGNL可以让我们用非常简单的表达式访问对象层,例如,当前环境的根对象为user1,则表达式per

Myself_jgl的专栏 830

理解Struts2中OGNL的使用

关于Struts2标签中,OGNL的使用问题,最近抽空整理了理解和使用OGNL的要点,分享一下1、理解Struts2中的ValueStackValueStack实际是一个接口,在Struts2中利用OGNL时,实际上使用的是实现了该接口的OgnlValueStack类,这个类是Struts2利用OGNL的基础。OgnlValueStack类的主要属性关系图如下:          

liaochangfa的专栏 764

深入理解Struts2的ognl标签

OGNL是Object-Graph Navigation Language的缩写,全称为对象图导航语言,是一种功能强大的表达式语言,它通过简单一致的语法,可以任意存取对象的属性或者调用对象的方法,能够遍历整个对象的结构图,实现对象属性类型的转换等功能。 此外,还得先需弄懂OGNL的一些知识:   1.OGNL表达式的计算是围绕OGNL上下文进行的。 OGNL上下文实际上就是一个Map对象,

一个执着的程序员 1484

简单理解OGNL、ActionContext、ValueStack

Struts2将ActionContext设置为OGNL上下文,并将值栈作为OGNL的根对象放置到ActionContext中。 可以在值栈中放入、删除、查询对象。访问值栈中的对象不用“#”。 Struts2总是把当前Action实例放置在栈顶。所以在OGNL中引用Action中的属性也可以省略“#”。 OGNL中重要的3个符号:#、%、$: 1.#符号 #符号的用途一般有三种。

老杨的专栏 1156

Ognl理解版

1、学习Ognl语法 学习OGNL语法 - 掘金

weixin_35821291的博客 73

java el ognl_EL与OGNL以及值栈的理解

这里先添加下在项目遇到的问题:这两天在做论坛项目的时候,犯了一个错误:将数据放入值栈中,结果jsp页面获取不到。困扰了许久:总结如下:(1)每个action对应相应页面的值栈中值的获取,在属于此action的页面上面如果采用OGNL或者EL表达式获取的值都是从此action中获取的。不要将action对应的页面搞乱了(2)关于EL表达式获取值栈中心的:map和对象栈stack中的值的获取方式:对于...

weixin_34108829的博客 150

struts2之ognl(偏理解方面)

转载请标明出处:https://blog.youkuaiyun.com/men_ma/article/details/106847165. 本文出自 不怕报错 就怕不报错的小猿猿 的博客 struts2之ognl(偏理解方面)一级目录二级目录三级目录 一级目录 二级目录 三级目录 ...

men_ma的博客 297

OGNL入门 及 理解

package org.darkness.ognl.test; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import junit.framework.TestCase; import ognl.Ognl; import or...

john521 129
上一篇: 牛人2
下一篇: jvm何时对类进行初始化及创建类实例的几种方法
john521
博客等级 码龄20年 17粉丝 253原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值