RuoYi-Vue-Plus (SPEL 表达式)

 RuoYi-Vue-Plus 中SPEL使用

DataScopeType 枚举类中:
/*** 部门数据权限*/DEPT("3", " #{#deptName} = #{#user.deptId} ", " 1 = 0 "),
PlusDataPermissionHandler 拦截器中定义了解析器:

        buildDataFilter 方法中根据注解的key value来进行SPEL解析:key作为占位符,value 设置进原生sql

@Slf4j
public class PlusDataPermissionHandler {  /*** spel 解析器*/private final ExpressionParser parser = new SpelExpressionParser();private final ParserContext parserContext = new TemplateParserContext();/*** 构造数据过滤sql*/private String buildDataFilter(DataColumn[] dataColumns, boolean isSelect) {。。。。。省略代码for (DataColumn dataColumn : dataColumns) {if (dataColumn.key().length != dataColumn.value().length) {throw new ServiceException("角色数据范围异常 => key与value长度不匹配");}if (!StringUtils.containsAny(type.getSqlTemplate(),Arrays.stream(dataColumn.key()).map(key -> "#" + key).toArray(String[]::new))) {continue;}//1- 设置注解变量 key 为表达式变量 value 为变量值for (int i = 0; i < dataColumn.key().length; i++) {context.setVariable(dataColumn.key()[i], dataColumn.value()[i]);}//2- 解析sql模板并填充String sql = parser.parseExpression(type.getSqlTemplate(), parserContext).getValue(context, String.class);conditions.add(joinStr + sql);isSuccess = true;}。。。。。省略代码}

一、概念

表达式语言给静态Java语言增加了动态功能。

SpEL是单独模块,只依赖于core模块,不依赖于其他模块,可以单独使用。

SpEL支持如下表达式:

一、基本表达式: 字面量表达式、关系,逻辑与算数运算表达式、字符串连接及截取表达式、三目运算及Elivis表达式、正则表达式、括号优先级表达式;

二、类相关表达式: 类类型表达式、类实例化、instanceof表达式、变量定义及引用、赋值表达式、自定义函数、对象属性存取及安全导航表达式、对象方法调用、Bean引用;

三、集合相关表达式: 内联List、内联数组、集合,字典访问、列表,字典,数组修改、集合投影、集合选择;不支持多维内联数组初始化;不支持内联字典定义;

四、其他表达式:模板表达式。

二、DEMO 测试:

@Testpublic void test1() {//1-首先构造一个解析器ExpressionParser parser = new SpelExpressionParser();//2-其次解析器解析字符串表达式Expression expression = parser.parseExpression("('Hello' + ' World').concat(#end)");//3- 创建上下文EvaluationContext context = new StandardEvaluationContext();//4-替换context.setVariable("end", "!");//5-求值:通过Expression接口的getValue方法,传入上下文获得表达式值。System.out.println(expression.getValue(context));}

1- parser.parseExpression("('Hello' + ' World').concat(#end)");

上面表达式拼接了 #end

2- context.setVariable("end", "!");

上下文中#end 替换为 !

输出:

Hello World!

三、ExpressionParser接口

public interface ExpressionParser {Expression parseExpression(String expressionString) throws ParseException;Expression parseExpression(String expressionString, ParserContext context) throws ParseException;
}

 Expression parseExpression(String expressionString, ParserContext context) 

传入 ParserContext  的实现类 TemplateParserContext 可以自定义解析前缀。

public interface ParserContext {//是否是模板boolean isTemplate();//模板表达式前缀String getExpressionPrefix();//模板表达式后缀String getExpressionSuffix();
}

 对上面DEMO案列更改:

@Testpublic void test1() {ExpressionParser parser = new SpelExpressionParser();//    ${ 定义解析前缀Expression expression = parser.parseExpression("HelloWorld${#end}", new TemplateParserContext("${","}") );EvaluationContext context = new StandardEvaluationContext();context.setVariable("end", "!");。System.out.println(expression.getValue(context));}

 表达式模版例子:

TemplateParserContext 解析器使用

@Test
public void test11() {//创建解析器SpelExpressionParser parser = new SpelExpressionParser();//创建解析器上下文ParserContext context = new TemplateParserContext("%{", "}");Expression expression = parser.parseExpression("你好:%{#name},我们正在学习:%{#lesson}", context);//创建表达式计算上下文EvaluationContext evaluationContext = new StandardEvaluationContext();evaluationContext.setVariable("name", "路人甲java");evaluationContext.setVariable("lesson", "spring高手系列!");//获取值String value = expression.getValue(evaluationContext, String.class);System.out.println(value);
}

四、EvaluationContext接口

表示上下文环境,默认实现是org.springframework.expression.spel.support包中的StandardEvaluationContext类,

  1. 使用setRootObject方法来设置根对象,
  2. 使用setVariable方法来注册自定义变量,
  3. 使用registerFunction来注册自定义函数等等。

五、 SPEL 语法

1-基础字面量

SpEL支持的字面量包括:字符串、数字类型(int、long、float、double)、布尔类型、null类型。

@Test
public void test2() {ExpressionParser parser = new SpelExpressionParser();String str1 = parser.parseExpression("'Hello World!'").getValue(String.class);int int1 = parser.parseExpression("1").getValue(Integer.class);long long1 = parser.parseExpression("-1L").getValue(long.class);float float1 = parser.parseExpression("1.1").getValue(Float.class);double double1 = parser.parseExpression("1.1E+2").getValue(double.class);int hex1 = parser.parseExpression("0xa").getValue(Integer.class);long hex2 = parser.parseExpression("0xaL").getValue(long.class);boolean true1 = parser.parseExpression("true").getValue(boolean.class);boolean false1 = parser.parseExpression("false").getValue(boolean.class);Object null1 = parser.parseExpression("null").getValue(Object.class);System.out.println("str1=" + str1);System.out.println("int1=" + int1);System.out.println("long1=" + long1);System.out.println("float1=" + float1);System.out.println("double1=" + double1);System.out.println("hex1=" + hex1);System.out.println("hex2=" + hex2);System.out.println("true1=" + true1);System.out.println("false1=" + false1);System.out.println("null1=" + null1);
}

输出:

str1=Hello World!
int1=1
long1=-1
float1=1.1
double1=110.0
hex1=10
hex2=10
true1=true
false1=false
null1=null
2-算数表达式:

 SpEL支持加(+)、减(-)、乘(*)、除(/)、求余(%)、幂(^)运算。

SpEL还提供求余(MOD)和除(DIV)而外两个运算符,与“%”和“/”等价,不区分大小写。

//类型示例加减乘除int result1 = parser.parseExpression("1+2-3*4/2").getValue(Integer.class);//求余
int result2 = parser.parseExpression("4%3").getValue(Integer.class);//幂运算
int result3 = parser.parseExpression("2^3").getValue(Integer.class);

 输出:

-3 
1 
8

3-关系表达式 

等于(==)、不等于(!=)、大于(>)、大于等于(>=)、小于(<)、小于等于(<=),区间(between)运算。

@Test
public void test3() {ExpressionParser parser = new SpelExpressionParser();boolean v1 = parser.parseExpression("1>2").getValue(boolean.class);boolean between1 = parser.parseExpression("1 between {1,2}").getValue(boolean.class);System.out.println("v1=" + v1);System.out.println("between1=" + between1);
}

 输出:

v1=false
between1=true
 4-逻辑表达式

且(and或者&&)、或(or或者||)、非(!或NOT)。

@Test
public void test4() {ExpressionParser parser = new SpelExpressionParser();boolean result1 = parser.parseExpression("2>1 and (!true or !false)").getValue(boolean.class);boolean result2 = parser.parseExpression("2>1 && (!true || !false)").getValue(boolean.class);boolean result3 = parser.parseExpression("2>1 and (NOT true or NOT false)").getValue(boolean.class);boolean result4 = parser.parseExpression("2>1 && (NOT true || NOT false)").getValue(boolean.class);System.out.println("result1=" + result1);System.out.println("result2=" + result2);System.out.println("result3=" + result3);System.out.println("result4=" + result4);
}

输出:

result1=true
result2=true
result3=true
result4=false
5-正则表达式

使用“str matches regex

如“”将返回true;ExpressionParser parser = new SpelExpressionParser();boolean result1 = parser.parseExpression("'123' matches '\d{3}'").getValue(boolean.class);

输出:

true

6-表达式赋值 、表达式模版

如上面标题二,就是表达式赋值

如上面标题三,表达式模版

其他调用类方法,转换类型之类不常用,可以自行查看下面知乎文档链接 

总结

  1. Spel功能还是比较强大的,可以脱离spring环境独立运行
  2. spel可以用在一些动态规则的匹配方面,比如监控系统中监控规则的动态匹配;其他的一些条件动态判断等等
  3. 本文内容比较长,建议大家把案例都敲一遍,可以设置一些断点去研究一下源码,有问题的,欢迎大家留言交流。

 本文参考 :

玩转Spring中强大的spel表达式! - 知乎 (zhihu.com)icon-default.png?t=N7T8https://zhuanlan.zhihu.com/p/174786047

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/4681.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[LitCTF 2023]Ping、[SWPUCTF 2021 新生赛]error、[NSSCTF 2022 Spring Recruit]babyphp

[LitCTF 2023]Ping 尝试ping一下127.0.0.1成功了&#xff0c;但要查看根目录时提示只能输入IP 查看源代码&#xff0c;这段JavaScript代码定义了一个名为check_ip的函数&#xff0c;用于验证输入是否为有效的IPv4地址。并且使用正则表达式re来匹配IPv4地址的格式。 对于这种写…

机器学习:基于Sklearn、XGBoost框架,使用逻辑回归、支持向量机和XGBClassifier预测帕金森病

前言 系列专栏&#xff1a;机器学习&#xff1a;高级应用与实践【项目实战100】【2024】✨︎ 在本专栏中不仅包含一些适合初学者的最新机器学习项目&#xff0c;每个项目都处理一组不同的问题&#xff0c;包括监督和无监督学习、分类、回归和聚类&#xff0c;而且涉及创建深度学…

【已解决】Python Selenium chromedriver Pycharm闪退的问题

概要 根据不同的业务场景需求&#xff0c;有时我们难免会使用程序来打开浏览器进行访问。本文在pycharm中使用selenium打开chromedriver出现闪退问题&#xff0c;根据不断尝试&#xff0c;最终找到的问题根本是版本问题。 代码如下 # (1) 导入selenium from selenium import …

科研学习|论文解读——CVPR 2021 人脸造假检测(论文合集)

随着图像合成技术的成熟&#xff0c;利用一张人脸照片合成假视频/不良视频现象越来越多&#xff0c;严重侵犯个人隐私、妨碍司法公正&#xff0c;所以人脸造假检测越来越重要&#xff0c;学术界的论文也越来越多。 一、研究1 1.1 论文题目 Multi-attentional Deepfake Detecti…

自学Python爬虫js逆向(二)chrome浏览器开发者工具的使用

js逆向中很多工作需要使用浏览器中的开发者工具&#xff0c;所以这里以chrome为例&#xff0c;先把开发者工具的使用总结一下&#xff0c;后面用到的时候可以回来查询。 Google Chrome浏览器的开发者工具是前端开发者的利器&#xff0c;它不仅提供了丰富的功能用于开发、调试和…

什么是中间件?中间件有哪些?

什么是中间件&#xff1f; 中间件&#xff08;Middleware&#xff09;是指在客户端和服务器之间的一层软件组件&#xff0c;用于处理请求和响应的过程。 中间件是指介于两个不同系统之间的软件组件&#xff0c;它可以在两个系统之间传递、处理、转换数据&#xff0c;以达到协…

排序算法(2)快排

交换排序 思想&#xff1a;所谓交换&#xff0c;就是根据序列中两个记录键值的比较结果来对换这两个记录在序列中的位置&#xff0c;交换排序的特点是&#xff1a;将键值较大的记录向序列的尾部移动&#xff0c;键值较小的记录向序列的前部移动。 一、冒泡排序 public static…

uniapp:K线图,支持H5,APP

使用KLineChart完成K线图制作,完成效果: 1、安装KLineChart npm install klinecharts2、页面中使用 <template><view class="index"><!-- 上方选项卡 --><view class="kline-tabs"><view :style="{color: current==ite…

stm32单片机开发四、USART

串口的空闲状态时高电平&#xff0c;起始位是低电平&#xff0c;来打破空闲状态的高电平 必须要有停止位&#xff0c;停止位一般为一位高电平 串口常说的数据为8N1&#xff0c;其实就是8个数据位&#xff08;固定的&#xff09;&#xff0c;N就是none&#xff0c;也就是0个校验…

【多模态大模型】AI对视频内容解析问答

文章目录 1. 项目背景2. 直接对视频进行解析进行AI问答&#xff1a;MiniGPT4-Video2.1 MiniGPT4-Video效果 3. 对视频抽帧为图片再进行AI问答3.1 视频抽帧3.2 图片AI问答3.2.1 阿里通义千问大模型 Qwen-vl-plus3.2.2 Moonshot 1. 项目背景 最近在做一个项目,需要使用AI技术对视…

618科技嘉年华!五款极致科技产品,开启智能生活新篇章!

准备好迎接一年一度的618了吗&#xff1f;这不仅仅是一场购物的狂欢&#xff0c;更是一次科技的盛宴&#xff0c;一次智能生活的全新启航。今年&#xff0c;我们将带来五款令人瞩目的极致科技产品&#xff0c;它们将彻底颠覆你对智能生活的认知。从娱乐到工作&#xff0c;这些产…

百度语音识别的springboot应用

1、pom依赖 <dependency> <groupId>com.baidu.aip</groupId> <artifactId>java-sdk</artifactId> <version>4.16.18</version> </dependency> 2、测试的demo 创建语音识别应用 百度智能云-管理中心 (baidu.com) 代码中要…

常用图像加密技术-流密码异或加密

异或加密是最常用的一种加密方式&#xff0c;广泛的适用于图像处理领域。这种加密方式依据加密密钥生成伪随机序列与图像的像素值进行异或操作&#xff0c;使得原像素值发生变化&#xff0c;进而使得图像内容发生变化&#xff0c;达到保护图像内容的目的。 该加密方法是以图像…

基于python-flask技术的社区信息交流平台【数据库+15000文档】

预览 介绍 系统只需使用者通过电脑浏览器即可实现系统的访问和操作的WEB模式的信息化系统。为了保证系统数据的准确性、安全性的数据存储&#xff0c;系统应用MySQL数据库进行系统数据存储服务。根据对社区工作的深入调研和对社区居民的走访调查&#xff0c;详细分析整体系统的…

短信验证码绕过漏洞(一)

短信验证码绕过漏洞 0x01原理&#xff1a; 服务器端返回的相关参数作为最终登录凭证&#xff0c;导致可绕过登录限制。 危害&#xff1a;在相关业务中危害也不同&#xff0c;如找回密码&#xff0c;注册&#xff0c;电话换绑等地方即可形成高危漏洞&#xff0c;如果是一些普…

【VS+QT】visual studio 2022配置和搭建QT

一、下载QT 可以去QT官网下载:https://www.qt.io/product/development-tools。 直接安装。 二、安装qt插件 打开visual studio 2022&#xff0c;选择菜单栏中扩展->管理扩展 ,然后直接在vs插件市场搜索Qt Visual Studio Tools就行。 安装的时候根据提示&#xff0c;关闭…

YOLov5 + Gradio搭建简单的Web GUI

写在前面&#xff1a;当我们将模型训练出来了&#xff0c;此时就需要做UI界面给别人展示了。python提供的Gradio可以快速的搭建web页面。生成本地网址和公网网址&#xff0c;方面自己测试和用户测试。 一、安装 Gradio介绍 Gradio是一个开源的python库&#xff0c;用于构建机…

react完整项目搭建的思路

react完整项目搭建的思路 react完整项目搭建的思路1.使用creacte-react-app初始化项目2.安装所需插件:路由、网络、样式、组件库3.reactjs目录结构组织4. 配置路径别名4.配置路由5.网络配置,对axios进行封装》获取当前环境变量 6.配置代理解决跨域7.配置使用iconfont8.状态管理…

浅析扩散模型与图像生成【应用篇】(十七)——LDM

17. High-Resolution Image Synthesis with Latent Diffusion Models 该文首次提出在潜在特征空间中的扩散模型LDM&#xff0c;也是大名鼎鼎的Stable Diffusion&#xff08;SD&#xff09;模型的基础。不同于之前的扩散模型直接在图像维度上进行扩散和去噪&#xff0c;LDM首先训…

C++拷贝构造函数的合成

默认构造函数和拷贝构造函数在必要的时候才由编译期合成出来 文章目录 拷贝构造函数编译器合成拷贝构造函数的四种情况情况一 一个类有一个带有拷贝构造函数的类对象成员变量情况二 派生类的基类有一个拷贝构造函数类声明了一个或多个虚函数情况四 类派生自一个继承串联且有一个…