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");

然后后台直接执行

  1. 首先我们实现一个方法,用于动态加载函数
//动态加载方法
//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);
}
  1. 然后编写测试用例:
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的更多相关文章

  1. C#动态执行字符串(动态创建代码)

    在编写C#程序的时候,有时我们需要动态生成一些代码并执行.然而C#不像JavaScript有一个Eval函数,可以动态的执行代码.所有这些功能都要我们自己去完成.如下是实例. 动态创建代码: usin ...

  2. 几款不错的java表达式引擎

    mvel 比较老牌了,很强大,但是好久没更新了 参考地址: http://mvel.documentnode.com/ https://github.com/mvel/mvel ScriptEngin ...

  3. c# 动态执行脚本,相关的几个脚本引擎.

    Jint   嵌入式的javascript脚本支持引擎,一直都在更新,对各种方法支持也比较好,可以 C# 交互. https://github.com/sebastienros/jint Jurass ...

  4. mysql 字符串分割 和 动态执行拼接sql

    本人以前主要用的是MSSQL,最近项目在使用MYSQL,自己是一个 典型的小白.今天就记录一下 一个mysql存储过程,里面需要分割字符串和 动态执行sql语句. 关于字符串 分割我开始使用 LOCA ...

  5. 页面上动态编译及执行java代码

    本文地址:http://www.cnblogs.com/liaoyu/p/real-time-compile-and-run-java-code-web-app.html 最近看到同事在页面上编译和执 ...

  6. 获取对象属性类型、属性名称、属性值的研究:反射和JEXL解析引擎

    同步发布:http://www.yuanrengu.com/index.php/20170511.html 先简单介绍下反射的概念:java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所 ...

  7. 表达式引擎aviator

    Aviator是一个轻量级.高性能的Java表达式执行引擎, 本文内容主要来自于官方文档 简介 包依赖 使用手册 执行表达式 使用变量 exec 方法 调用函数 自定义函数 编译表达式 访问数组和集合 ...

  8. Javascript动态执行JS(new Function与eval比较)

    new Function与eval可以动态执行JS,只要把拼接好的JS方法,然后以字符串的形式传入到这两个函数,可以执行,其中new Function用在模板引擎比较多. 用 Function 类直接 ...

  9. 面向 Java 开发人员的 Ajax: 构建动态的 Java 应用程序

    面向 Java 开发人员的 Ajax: 构建动态的 Java 应用程序 Ajax 为更好的 Web 应用程序铺平了道路 在 Web 应用程序开发中,页面重载循环是最大的一个使用障碍,对于 Java™ ...

随机推荐

  1. Tensorflow 中(批量)读取数据的案列分析及TFRecord文件的打包与读取

    内容概要: 单一数据读取方式: 第一种:slice_input_producer() # 返回值可以直接通过 Session.run([images, labels])查看,且第一个参数必须放在列表中 ...

  2. Github删除分支下所有提交记录

    [本文版权归微信公众号"代码艺术"(ID:onblog)所有,若是转载请务必保留本段原创声明,违者必究.若是文章有不足之处,欢迎关注微信公众号私信与我进行交流!] 有时候,我们提交 ...

  3. Jmeter之仿真高并发测试-集合点

    场景: 大家在使用Jmeter测试的时候应该发现了, (1)线程启动了就会直接发送测试请求:--如果要模拟在一瞬间高并发量测试的时候,需要调高线程数量,这很耗测试机器的性能,往往无法支持较大的并发数, ...

  4. 资深阿里程序员一一为你解刨Web前端知识体系结构,付出与收获成正比!

    只要接触过前端,都会指导web前端的知识主要由三部分组成:分别为静态html,样式css,动态javascript(简称js)这三大部分组成.其三部分组成的一个体系的复杂程度不亚于其他一门技术的复杂程 ...

  5. linux terminal---EOF

    we can use cat and eof to enter multiple lines content once.

  6. Redis系列(十二):数据结构SortedSet跳跃表中基本操作命令和源码解析

    1.SkipList Redis的sortedSet数据结构是有序不重复的(索引为唯一的,数据(score)却可以重复), 跳表是redis的一个核心组件,也同时被广泛地运用到了各种缓存地实现当中,它 ...

  7. python抓取头条文章

    python抓取头条美文并存储到mongodb # Author:song from multiprocessing import Pool from urllib.parse import urle ...

  8. Guava RateLimiter限流器使用示例

    Guava中的RateLimiter可以限制单进程中某个方法的速率,本文主要介绍如何使用,实现原理请参考文档:推荐:超详细的Guava RateLimiter限流原理解析和推荐:RateLimiter ...

  9. flex布局语法+实例

    一.什么是flex布局 flex 是 flexible box 的缩写,意为"弹性布局",用来为盒状模型提供最大的灵活性. 任何一个容器都可以指定为 flex 布局.你可以将前端页 ...

  10. uni-app网络请求

    对于 GET 方法,会将数据转换为 query string.例如 { name: 'name', age: 18 } 转换后的结果是 name=name&age=18. 对于 POST 方法 ...