失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > Jexl表达式引擎-根据字符串动态执行JAVA

Jexl表达式引擎-根据字符串动态执行JAVA

时间:2021-12-02 06:26:00

相关推荐

Jexl表达式引擎-根据字符串动态执行JAVA

Table of Contentsgenerated with DocToc

一、使用场景二、市面上表达式引擎比较 2.1 Aviator2.2 Jexl

一、使用场景

在做某些项目的时候,有时会遇到如下情景:

用户需要传入某个JAVA 表达式,然后后台将这个表达式当作JAVA代码执行

二、市面上表达式引擎比较

我们有许多表达式引擎可供选择:

JexlAviator

2.1 Aviator

avitor具体使用技巧可以参考这篇博客:/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需要导入如下依赖:

<!-- /artifact/mons/commons-jexl --><dependency><groupId>mons</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<对象名,对象>@Beforepublic 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执行引擎@Testpublic void TestFunctionMethod(){String expression="user.getId().equals(id)";boolean res = (boolean) invokeMethod(expression,env);Assert.assertTrue(res);}}

执行结果为true

与Aviator相比,我们省去了修改表达式的步骤

如果觉得《Jexl表达式引擎-根据字符串动态执行JAVA》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。