Jexl表达式引擎-根据字符串动态执行JAVA.md
Table of Contents generated with DocToc
一、使用场景
在做某些项目的时候,有时会遇到如下情景:
用户需要传入某个JAVA 表达式,然后后台将这个表达式当作JAVA代码执行
二、市面上表达式引擎比较
我们有许多表达式引擎可供选择:
- Jexl
- Aviator
2.1 Aviator
avitor具体使用技巧可以参考这篇博客:https://blog.csdn.net/keda8997110/article/details/50782848
avitor可以满足基本的表达式的判断,但对于对象中的函数调用明显力不从心,如果碰到以下业务情景:
用户传入的java表达式是:user.getName().equals("123456");
这个表达式是调用user对象里的getName方法,然后再掉用equals方法,判断是否等于字符串123456,avitor对于调用对象的方法这个问题也有自己的解决方法:
User user = new User("123456");
//首先要注入User的类
AviatorEvaluator.addInstanceFunctions("user", User.class);
//再使用aviator特定的表达式运行方法: namespace.method(instance, args)
AviatorEvaluator.execute("User.getName(user)=='123456'")
这样太麻烦了,虽然程序可以事先将需要的类注入到AviatorEvaluator引擎中,但是我们还需要将熟悉的java表达式转化为Aviator需要的表达式形式。
那我们有没有可以直接执行java代码的呢?有!
2.2 Jexl
我们在maven中使用 Jexl 需要导入如下依赖:
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-jexl -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-jexl</artifactId>
<version>2.1.1</version>
</dependency>
然后看我们的 Jexl 如何实现业务:
用户传入的java表达式是:user.getName().equals("123456");
然后后台直接执行
- 首先我们实现一个方法,用于动态加载函数
//动态加载方法
//jexlExp -- java表达式
//map -- 运行环境
private Object invokeMethod(String jexlExp, Map<String,Object> map){
JexlEngine jexl=new JexlEngine();
Expression e = jexl.createExpression(jexlExp);
JexlContext jc = new MapContext();
for(String key:map.keySet()){
jc.set(key, map.get(key));
}
if(null==e.evaluate(jc)){
return "";
}
return e.evaluate(jc);
}
- 然后编写测试用例:
pubic class User{
String name = "123456";
public User(String name){
this.name = name;
}
public String getName(){
return name;
}
}
public class JexlTest {
private Map<String, Object> env;
//注入测试环境,将变量形成一个map<对象名,对象>
@Before
public void before(){
env = new HashMap<>();
env.put("id","123456");
env.put("user",new User());
}
//动态加载方法
private Object invokeMethod(String jexlExp, Map<String,Object> map){
JexlEngine jexl=new JexlEngine();
Expression e = jexl.createExpression(jexlExp);
JexlContext jc = new MapContext();
for(String key:map.keySet()){
jc.set(key, map.get(key));
}
if(null==e.evaluate(jc)){
return "";
}
return e.evaluate(jc);
}
//调用Jexl执行引擎
@Test
public void TestFunctionMethod(){
String expression="user.getId().equals(id)";
boolean res = (boolean) invokeMethod(expression,env);
Assert.assertTrue(res);
}
}
执行结果为true
与Aviator相比,我们省去了修改表达式的步骤
Jexl表达式引擎-根据字符串动态执行JAVA.md的更多相关文章
- C#动态执行字符串(动态创建代码)
在编写C#程序的时候,有时我们需要动态生成一些代码并执行.然而C#不像JavaScript有一个Eval函数,可以动态的执行代码.所有这些功能都要我们自己去完成.如下是实例. 动态创建代码: usin ...
- 几款不错的java表达式引擎
mvel 比较老牌了,很强大,但是好久没更新了 参考地址: http://mvel.documentnode.com/ https://github.com/mvel/mvel ScriptEngin ...
- c# 动态执行脚本,相关的几个脚本引擎.
Jint 嵌入式的javascript脚本支持引擎,一直都在更新,对各种方法支持也比较好,可以 C# 交互. https://github.com/sebastienros/jint Jurass ...
- mysql 字符串分割 和 动态执行拼接sql
本人以前主要用的是MSSQL,最近项目在使用MYSQL,自己是一个 典型的小白.今天就记录一下 一个mysql存储过程,里面需要分割字符串和 动态执行sql语句. 关于字符串 分割我开始使用 LOCA ...
- 页面上动态编译及执行java代码
本文地址:http://www.cnblogs.com/liaoyu/p/real-time-compile-and-run-java-code-web-app.html 最近看到同事在页面上编译和执 ...
- 获取对象属性类型、属性名称、属性值的研究:反射和JEXL解析引擎
同步发布:http://www.yuanrengu.com/index.php/20170511.html 先简单介绍下反射的概念:java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所 ...
- 表达式引擎aviator
Aviator是一个轻量级.高性能的Java表达式执行引擎, 本文内容主要来自于官方文档 简介 包依赖 使用手册 执行表达式 使用变量 exec 方法 调用函数 自定义函数 编译表达式 访问数组和集合 ...
- Javascript动态执行JS(new Function与eval比较)
new Function与eval可以动态执行JS,只要把拼接好的JS方法,然后以字符串的形式传入到这两个函数,可以执行,其中new Function用在模板引擎比较多. 用 Function 类直接 ...
- 面向 Java 开发人员的 Ajax: 构建动态的 Java 应用程序
面向 Java 开发人员的 Ajax: 构建动态的 Java 应用程序 Ajax 为更好的 Web 应用程序铺平了道路 在 Web 应用程序开发中,页面重载循环是最大的一个使用障碍,对于 Java™ ...
随机推荐
- 1169A+B问题终结版(高精度计算)
描述 给定两个整数A和B,输出A+B的值.A和B的值可能会很大很大,甚至达到100位.现在请你解决这一问题. 输入 两行,分别是两个整数A,B,换行隔开.A和B会很大很大. 输出 一个整数,即A+B的 ...
- 如何用 React 构建前端架构
早期的前端是由后端开发的,最开始的时候仅仅做展示,点一下链接跳转到另外一个页面去,渲染表单,再用Ajax的方式请求网络和后端交互,数据返回来还需要把数据渲染到DOM上.写这样的代码的确是很简单.在We ...
- Perl入门(三)Perl的数组
Perl数组的声明方式 Perl使用"@"符号声明一个数组:@array: 使用"()"或"qw()"声明数组中元素: 一个完整的声明方式为 ...
- Spring-AOP:一、注解demo及基本概念
切面:Aspect 切面=切入点+通知.在老的spring版本中通常用xml配置,现在通常是一个类带上@Aspect注解.切面负责将 横切逻辑(通知) 编织 到指定的连接点中. 目标对象:Target ...
- IDEA2019版中文汉化包
废话不多说,上才艺 E G M~~~~~ 2020版的IDEA大佬可以无视........ 1.打开IDEA文件目录 2.打开lib目录--将汉化版复制到该目录下 3.打开IDEA查看效果 高铁链 ...
- Redis系列(六):数据结构List双向链表LPUSH、LPOP、RPUSH、RPOP、LLEN命令
1.介绍 redis中的list既实现了栈(先进后出)又实现了队列(先进先出) 1.示意图 2.各命令详解 LPUSH/RPUSH LPUSH: 从队列的左边入队一个或多个元素 将所有指定的值插入到存 ...
- BOM问题-对于php的影响
甲.BOM说明 BOM(Byte Order Mark),是UTF编码方案里用于标识编码的标准标记.这个标记是可选的,UTF-8不需要BOM来表明字节顺序,但可以用BOM来表明当前编码方式.但如果文件 ...
- 【总结】Array、ArrayList、List
一.Array(数组) 1.申明时必须要指定数组长度. 2.数据类型安全. 申明数组如下: 1 class Program 2 { 3 static void Main(string[] args) ...
- JavaScript基础函数体中的唯一var模式(002)
全局变量是不好的.所以在声名变量的时候,应该采用函数体中的唯一var模式(Single var Pattern).这个模式有不少好处: 提供了一个唯一的地方来查看函数体中声名的变量 在使用一个变量之前 ...
- [CEOI1999]Parity Game 题解
P5937 [CEOI1999]Parity Game 洛谷P5937 P5937 [CEOI1999]Parity Game 前言: 个人感觉这道题初看想不到并查集啊!(说实话我题都没读懂,第二遍才 ...