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 总结 大家好,我是欧阳方超,可以我的公众号“欧阳方超”,后续内容…...
【Linux】shell脚本忽略错误继续执行
在 shell 脚本中,可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行,可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令,并忽略错误 rm somefile…...
vscode(仍待补充)
写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh? debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...
CentOS下的分布式内存计算Spark环境部署
一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架,相比 MapReduce 具有以下核心优势: 内存计算:数据可常驻内存,迭代计算性能提升 10-100 倍(文档段落:3-79…...
第25节 Node.js 断言测试
Node.js的assert模块主要用于编写程序的单元测试时使用,通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试,通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...
土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等
🔍 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术,可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势,还能有效评价重大生态工程…...
JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作
一、上下文切换 即使单核CPU也可以进行多线程执行代码,CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短,所以CPU会不断地切换线程执行,从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...
Android Bitmap治理全解析:从加载优化到泄漏防控的全生命周期管理
引言 Bitmap(位图)是Android应用内存占用的“头号杀手”。一张1080P(1920x1080)的图片以ARGB_8888格式加载时,内存占用高达8MB(192010804字节)。据统计,超过60%的应用OOM崩溃与Bitm…...
Rapidio门铃消息FIFO溢出机制
关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系,以下是深入解析: 门铃FIFO溢出的本质 在RapidIO系统中,门铃消息FIFO是硬件控制器内部的缓冲区,用于临时存储接收到的门铃消息(Doorbell Message)。…...
Java多线程实现之Thread类深度解析
Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...
快刀集(1): 一刀斩断视频片头广告
一刀流:用一个简单脚本,秒杀视频片头广告,还你清爽观影体验。 1. 引子 作为一个爱生活、爱学习、爱收藏高清资源的老码农,平时写代码之余看看电影、补补片,是再正常不过的事。 电影嘛,要沉浸,…...
