OGNL表达式
介绍
OGNL生来就是为了简化Java属性的取值,比如想根据名称name引用当前上下文环境中的对象,则直接键入即可,如果想要引用当前上下文环境中对象text的属性title,则键入text.title即可。如果想引用对象的非值属性,OGNL也是支持的:
| 属性类型 | 举例 |
| 属性名称 | 比如上文中的name |
| 属性方法 | hashcode()返回当前对象的哈希值 |
| 数组索引 | arrays\[0\]返回返回arrays数组的第一个元素 |
OGNL表达式用于用于访问对象的字段、方法。所以我们在使用OGNL表达式的时候需要一个对象,这在OGNL表达式中被称为root对象,以此来声明由哪个对象来执行这个表达式,返回结果。所有的OGNL表达式都在一个特定的数据环境中运行。OGNL的上下文环境是一个Map结构,称之为OgnlContext。Root对象也会被添加到上下文环境当中。
依赖引入
<dependency><groupId>ognl</groupId><artifactId>ognl</artifactId><version>3.4.1</version>
</dependency>
OGNL三要素
- 表达式(Expression):
表达式是整个 OGNL 的核心内容,所有的 OGNL 操作都是针对表达式解析后进行的。通过表达式来告诉 OGNL 操作到底要干些什么。因此,表达式其实是一个带有语法含义的字符串,整个字符串将规定操作的类型和内容。OGNL 表达式支持大量的表达式,如 “链式访问对象”、表达式计算、甚至还支持 Lambda 表达式。
- Root 对象:
OGNL 的 Root 对象可以理解为 OGNL 的操作对象。当我们指定了一个表达式的时候,我们需要指定这个表达式针对的是哪个具体的对象。而这个具体的对象就是 Root 对象,这就意味着,如果有一个 OGNL 表达式,那么我们需要针对 Root 对象来进行 OGNL 表达式的计算并且返回结果。
- 上下文环境:
有个 Root 对象和表达式,我们就可以使用 OGNL 进行简单的操作了,如对 Root 对象的赋值与取值操作。但是,实际上在 OGNL 的内部,所有的操作都会在一个特定的数据环境中运行。这个数据环境就是上下文环境(Context)。OGNL 的上下文环境是一个 Map 结构,称之为 OgnlContext。Root 对象也会被添加到上下文环境当中去。
说白了上下文就是一个 MAP 结构,它实现了 java.utils.Map 的接口。
使用 Ognl
假设有一个User类,包含用户的姓名和年龄,以及一个Address类用于表示用户的地址。通过OGNL表达式,我们可以访问和修改这些属性。
public class User {private String name;private int age;private Address address;public User(String name, int age, Address address) {this.name = name;this.age = age;this.address = address;}
}
在这里,我们假设使用OGNL库来解析和执行表达式。可以用Ognl.parseExpression解析表达式,用Ognl.getValue获取值或用Ognl.setValue设置值。
import ognl.Ognl;
import ognl.OgnlContext;
import ognl.OgnlException;public class OgnlExample {public static void main(String[] args) throws OgnlException {// 创建用户对象Address address = new Address("New York", "5th Avenue");User user = new User("Alice", 25, address);// 创建OGNL上下文OgnlContext context = new OgnlContext();context.put("user", user); // 将对象放入上下文context.setRoot(user); // 设置根对象// 获取用户的名称Object nameExpr = Ognl.parseExpression("name");String name = (String) Ognl.getValue(nameExpr, context, user);System.out.println("User's name: " + name); // 输出 "User's name: Alice"// 获取用户的城市Object cityExpr = Ognl.parseExpression("address.city");String city = (String) Ognl.getValue(cityExpr, context, user);System.out.println("User's city: " + city); // 输出 "User's city: New York"// 修改用户的年龄Object ageExpr = Ognl.parseExpression("age");Ognl.setValue(ageExpr, context, user, 30);System.out.println("User's new age: " + user.getAge()); // 输出 "User's new age: 30"// 条件判断Object isAdultExpr = Ognl.parseExpression("age > 18 ? 'Adult' : 'Minor'");String isAdult = (String) Ognl.getValue(isAdultExpr, context, user);System.out.println("User is an: " + isAdult); // 输出 "User is an: Adult"}
}
相关文章:
OGNL表达式
介绍 OGNL生来就是为了简化Java属性的取值,比如想根据名称name引用当前上下文环境中的对象,则直接键入即可,如果想要引用当前上下文环境中对象text的属性title,则键入text.title即可。如果想引用对象的非值属性,OGNL也…...
AI 大模型重塑软件开发流程的现状与未来展望
 大家好,我是程序员小羊! 前言: 随着AI技术,尤其是大模型的快速发展,软件开发领域正在经历深刻…...
Spring Boot 的核心注解
一、引言 Spring Boot 作为一种流行的 Java 开发框架,以其简洁高效的开发方式受到广泛关注。其中,核心注解在 Spring Boot 应用的开发中起着至关重要的作用。理解这些注解的含义和用法,对于充分发挥 Spring Boot 的优势至关重要。本文将深入剖…...
蓝桥杯备考——算法
一、排序 冒泡排序、选择排序、插入排序、 快速排序、归并排序、桶排序 二、枚举 三、二分查找与二分答案 四、搜索(DFS) DFS(DFS基础、回溯、剪枝、记忆化) 1.DFS算法(深度优先搜索算法) 深度优先搜…...
MutationObserver与IntersectionObserver的区别
今天主要是分享一下MutationObserver和IntersectionObserver的区别,希望对大家有帮助! MutationObserver 和 IntersectionObserver 的区别 MutationObserver 作用:用于监听 DOM 树的变动,包括:元素的属性、子元素列表或节点文本的…...
生产与配置
1.鲁滨孙克苏鲁经济 鲁滨孙克苏鲁经济是一种非常简单的自给自足的经济,劳动时间与休息时间总和为总的时间。 即 摘椰子的数量为劳动时间的函数 由于鲁滨孙喜欢椰子,厌恶劳动时间,因此无差异曲线表现为厌恶品的形态。 根据无差异曲线和生…...
Android Kotlin Flow 冷流 热流
在 Android 开发中,Flow 是 Kotlin 协程库的一部分,用于处理异步数据流的一个组件。本质上,Flow 是一个能够异步生产多个值的数据流,与 suspend 函数返回单个值的模式相对应。Flow 更类似于 RxJava 中的 Observable,但…...
订单日记助力“实峰科技”提升业务效率
感谢北京实峰科技有限公司选择使用订单日记! 北京实峰科技有限公司,成立于2022年,位于北京市石景区,是一家以从事生产、销售微特电机、输配电及控制设备等业务为主的企业。 在业务不断壮大的过程中,想使用一种既能提…...
如何安装和配置JDK17
教程目录 零、引言1、新特性概览2、性能优化3、安全性增强4、其他改进5、总结 一、下载安装二、环境配置三、测试验证 零、引言 JDK 17(Java Development Kit 17)是Java平台的一个重要版本,它带来了许多新特性和改进,进一步提升了…...
智能化温室大棚控制系统设计(论文+源码)
1 系统的功能及方案设计 本次智能化温室大棚控制系统的设计其系统整体结构如图2.1所示,整个系统在器件上包括了主控制器STC89C52,温湿度传感器DHT11,LCD1602液晶,继电器,CO2传感器,光敏电阻,按…...
面试题之---解释一下原型和原型链
实例化对象 和普调函数一样,只不过调用的时候要和new连用(实例化),不然就是一个普通函数调用 function Person () {} const o1 new Person() //能得到一个空对象 const o2 Person() //什么也得不到,这就是普通的…...
【Leecode】Leecode刷题之路第46天之全排列
题目出处 46-全排列-题目出处 题目描述 个人解法 思路: todo代码示例:(Java) todo复杂度分析 todo官方解法 46-全排列-官方解法 预备知识 回溯法:一种通过探索所有可能的候选解来找出所有的解的算法。如果候选解…...
自动驾驶革命:从特斯拉到百度,谁将主宰未来交通?
内容概要 自动驾驶技术正在经历一个前所未有的革命性变化,各大企业纷纷抢占这一充满潜力的新市场。以特斯拉和百度为代表的行业巨头,正利用各自的优势在这一技术的赛道上展开激烈竞争。特斯拉凭借其在电动汽车和自动驾驶领域的前瞻性设计与不断革新的技…...
Python __str__()方法
在Python中,str() 方法是一个特殊的方法(也称为魔术方法或双下方法),它定义了当对象需要被转换为字符串表示时应该如何做。 当你尝试打印对象(使用 print() 函数)或将对象插入到需要字符串表示的上下文中&…...
虚拟机的安装
添加映像文件 自动或者手动分配磁盘 添加密码 创建用户 创建快照...
HCIP快速生成树 RSTP
STP(Spanning Tree Protocol,生成树协议)和RSTP(Rapid Spanning Tree Protocol,快速生成树协议)都是用于在局域网中消除环路的网络协议。 STP(生成树协议) 基本概念: ST…...
Python基础学习-05元组 tuple
目录 1、元组的定义 2、元组的切片和索引 3、元组的函数 4、二维元组 5、本节总结 1、元组的定义 • 基本上可以理解为一个不可改变的列表 • 元组没有列表那么常用,但是它的关键是不可改变性 • 使用() 定义一个元组 1) T (1, 2, 3, 4, …...
vue3 基于element-plus进行的一个可拖动改变导航与内容区域大小的简单方法
1、先上个截图: 说明:拖动上面的分隔栏就可以实现,改变左右区域的大小。 2、上面的例子来自官网的: Container 布局容器 | Element Plus 3、拖动的效果来自: https://juejin.cn/post/7029640316999172104#heading-1…...
c++基础28函数的类型
函数的类型 基本用法例子usingfucntion 基本用法 在C中,函数类型是指函数的签名,包括返回类型、参数类型以及参数的数量。函数类型可以用来声明函数指针、函数引用或者作为模板参数。 函数也可当成一种数据类型 函数指针: 函数指针可以指向…...
Elasticsearch(四):query_string查询介绍
query_string查询介绍 1 概述2 基本概念3 数据准备4 query_string查询示例4.1 基本查询4.2 复杂查询解析4.3 高级过滤解析4.4 模糊查询解析4.5 高亮查询解析4.6 分页查询解析 5 总结 大家好,我是欧阳方超,可以我的公众号“欧阳方超”,后续内容…...
Zynq/ZynqMP PL端以太网实战:手把手教你用GMII to RGMII IP和EMIO打通网络(附KSZ9031 PHY驱动修改)
Zynq/ZynqMP PL端以太网实战:从硬件配置到驱动适配全流程解析 在嵌入式系统开发中,以太网通信是许多项目的核心需求。当我们需要在Zynq或ZynqMP平台上实现PL端以太网功能时,往往会遇到硬件IP配置和PHY驱动适配两大挑战。本文将带你完整走通从…...
多模态AI处理利器:基于MCP协议的Stitch-Pro服务器架构解析
1. 项目概述:一个面向多模态内容处理的“缝合”利器 最近在折腾一个挺有意思的开源项目,叫 stitch-pro-mcp 。这个名字挺直白,“stitch”是缝合,“pro”是专业版,“mcp”则指向了“模型上下文协议”。简单来说&#…...
告别手动下载!3步轻松批量获取网易云音乐FLAC无损音乐
告别手动下载!3步轻松批量获取网易云音乐FLAC无损音乐 【免费下载链接】NeteaseCloudMusicFlac 根据网易云音乐的歌单, 下载flac无损音乐到本地.。 项目地址: https://gitcode.com/gh_mirrors/nete/NeteaseCloudMusicFlac 你是不是也遇到过这样的烦恼&#x…...
Unity项目瘦身实战:彻底搞懂Library文件夹,轻松清理几十个G的缓存
Unity项目瘦身实战:彻底搞懂Library文件夹,轻松清理几十个G的缓存 当你打开资源管理器,发现Unity项目的Library文件夹已经吞噬了50GB磁盘空间时,那种窒息感就像发现衣柜里塞满了十年没穿过的旧衣服。这个隐藏在项目根目录下的&quo…...
西门子S7-300/400跨网段数据交换:DP/DP Coupler模块的Step7组态避坑指南
西门子S7-300/400跨网段数据交换实战:DP/DP Coupler组态深度解析与故障排查 在工业自动化系统中,多套PLC之间的数据交互是常见需求。当这些PLC分布在不同Profibus-DP网络时,西门子DP/DP Coupler模块成为实现跨网段通讯的关键组件。然而&#…...
Go语言规则同步器airulesync:自动化聚合与更新网络过滤规则
1. 项目概述:一个自动同步上游规则的“规则同步器”如果你和我一样,长期在维护自己的网络过滤规则集,无论是用于广告屏蔽、隐私保护还是内容过滤,那么你一定对“规则更新”这件事深有体会。手动去各个开源项目的主页查看更新、下载…...
从行业会议议程到个人技能地图:嵌入式工程师系统化成长指南
1. 从行业盛会到个人技能地图:如何将MASTERs会议的精髓转化为你的嵌入式成长引擎又到了一年一度技术人“充电”的季节。如果你在工业自动化、电机控制或者机器人领域深耕,那么对Microchip Technology这家公司及其产品线一定不会陌生。每年夏天࿰…...
Wireshark 命令行实战指南 ———— 自动化抓包与高效分析
1. 为什么需要Wireshark命令行模式 很多网络工程师第一次接触Wireshark时,都是通过图形界面进行操作。鼠标点点就能开始抓包,确实很方便。但当你需要处理以下场景时,图形界面就显得力不从心了: 服务器环境没有图形界面,…...
不止于导航:用AI Habitat的语义分割数据,教你构建自己的室内物体识别与场景理解Pipeline
不止于导航:用AI Habitat的语义分割数据构建室内物体识别与场景理解Pipeline 在计算机视觉与机器人领域,室内场景理解一直是极具挑战性的研究方向。传统方法依赖于昂贵的传感器设备和人工标注数据,而仿真平台的出现为这一领域带来了革命性变…...
从Awesome List到实战:构建你的AI编程工作流与Vibe Coding环境
1. 从“Awesome List”到“Vibe Coding”实战指南:如何构建你的AI编程工作流如果你最近在GitHub上逛过,或者关注AI编程工具的圈子,大概率会刷到一个叫“Awesome Vibe Coding”的仓库。乍一看,它像是一个又一个AI工具和项目的简单罗…...
