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. .NET进行客户端Web开发又一利器 - Ant Design Blazor

    你好,我是Dotnet9,继上篇介绍Bootstrap风格的BlazorUI组件库后,今天我来介绍另一款Blazor UI组件库:一套基于 Ant Design 和 Blazor 的企业级组件库. 本 ...

  2. LeetCode 79,这道走迷宫问题为什么不能用宽搜呢?

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是LeetCode专题第48篇文章,我们一起来看看LeetCode当中的第79题,搜索单词(Word Search). 这一题官方给的难 ...

  3. PHP控制阿里云短信API接口实现短信群发功能

    阿里云短信支持先使用后支付的原则,价格为4分半1条. 通过SDK可以与网站功能的绑定,实现响应的短信发送功能 现已统一合并升级为:消息服务. 消息服务 阿里云消息服务(Message Service, ...

  4. Spring—容器外的Bean使用依赖注入

    认识AutowireCapableBeanFactory AutowireCapableBeanFactory是在BeanFactory的基础上实现对已存在实例的管理.可以使用这个接口集成其他框架,捆 ...

  5. SQL注入之报错注入常见函数

  6. Mariadb之事务隔离级别

    上一篇我们聊到了mariadb的锁,以及怎么手动加锁和解锁等等,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/13196905.html:今天我们来聊一聊mar ...

  7. 如何理解nginx反向代理,其实叫逆向代理更容易让我理解

    接触nginx后,以我的语文水平,一直无法理解它神奇的名字:反向代理 怎么就反向了?反哪里去了 (以下部分图片.内容来自网络整理) 1.先理解正向代理 正向代理( Forward Proxy ): 客 ...

  8. flask的小错误

    这几天刚学flask,根据录屏学代码的时候,遇到一个问题 基本能看懂错误,role_id是类的一个字段,应该是一个对象,最后发现是单词写错了,应该是大写的Column, db.Column(db.In ...

  9. 2.Unity3d常用按键

    Unity3d常用按键和组合键: 1.鼠标左键:选中物体 2.鼠标中键:平移视角,和手型功能一样 3.鼠标右键:旋转观察角度 4.Alt+鼠标左键:旋转观察角度 5.Alt+鼠标右键:拉远拉近

  10. __FILE__和__DIR__的用法

    dirname(__FILE__)由两部分组成, __FILE__ 魔术变量和 dirname() 函数.__FILE__是当前脚本的绝对路径,通过 dirname() 函数后,就可以获得脚本所在目录 ...