java怎么动态匹配字符串_Jexl表达式引擎-根据字符串动态执行JAVA

Table of Contents generated with DocToc

一、使用场景

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

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

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

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

Jexl

Aviator

2.1 Aviator

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 需要导入如下依赖:

org.apache.commons

commons-jexl

2.1.1

然后看我们的 Jexl 如何实现业务:

用户传入的java表达式是:user.getName().equals(“123456”);

然后后台直接执行

首先我们实现一个方法,用于动态加载函数

//动态加载方法

//jexlExp -- java表达式

//map -- 运行环境

private Object invokeMethod(String jexlExp, Map 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 env;

//注入测试环境,将变量形成一个map

@Before

public void before(){

env = new HashMap<>();

env.put("id","123456");

env.put("user",new User());

}

//动态加载方法

private Object invokeMethod(String jexlExp, Map 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相比,我们省去了修改表达式的步骤

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值