Java8使用ScriptEngine动态执行js及规则引擎jexl3、groovy的使用

基础入门

public static void javaCallJS() {
    ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
    ScriptEngine scriptEngine = scriptEngineManager.getEngineByName("nashorn");

    String name = "Jaemon";
    Integer result = null;

    try {
        scriptEngine.eval("print('" + name + "')");
        result = (Integer) scriptEngine.eval("10 + 2");
    } catch (ScriptException e) {
        e.printStackTrace();
    }
    System.out.println(result.toString());
}

输出结果

Jaemon
12

 

执行js函数

public static void javaCallJS() throws Exception {
    ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
    ScriptEngine scriptEngine = scriptEngineManager.getEngineByName("JavaScript");
    String script = "function add(x, y) { return x + y;}";
    scriptEngine.eval(script);
    Invocable invocable = (Invocable) scriptEngine;
    Object result = invocable.invokeFunction("add", new Object[]{10, 20});
    System.out.println("result=" + result);
}

输出结果

result=30.0

 

将变量传入js脚本

public static void javaCallJS() throws Exception {
    ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
    ScriptEngine scriptEngine = scriptEngineManager.getEngineByName("JavaScript");
    String script = "Math.pow(x, y)";
    Map<String, Object> params = Maps.newHashMap();
    params.put("x", 10);
    params.put("y", 2);
    Object result = scriptEngine.eval(script, new SimpleBindings(params));
    System.out.println("result=" + result);
}

输出结果

result=100.0

 

执行js语句块

如果现在知道参数值为: {“company”: 2, “amt”: 200},判断如下规则的执行结果

if (company == 1) {
  return true;
} else if (company == 2 && amt > 100) {
  return true;
} else if (company == 3 && amt > 200) {
  return true;
} else {
  return false;
}

实现方式如下

public static void javaCallJS() throws Exception {
    ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
    ScriptEngine scriptEngine = scriptEngineManager.getEngineByName("JavaScript");
    // 待执行语句块
    String script = "" +
        "if (company == 1) {\n" +
        "  return true;\n" +
        "} else if (company == 2 && amt > 100) {\n" +
        "  return true;\n" +
        "} else if (company == 3 && amt > 200) {\n" +
        "  return true;\n" +
        "} else {\n" +
        "  return false;\n" +
        "}";
    // 参数列表名称
    String paramsName = "company, amt";
    String executeScript = String.format(
        "function execute(%s) { %s }", paramsName, script
    );
    
    scriptEngine.eval(executeScript);
    Invocable jsInvoke = (Invocable) scriptEngine;
    
    System.out.println(jsInvoke.invokeFunction("execute", new Object[]{1, 100}));
    System.out.println(jsInvoke.invokeFunction("execute", new Object[]{2, 100}));
    System.out.println(jsInvoke.invokeFunction("execute", new Object[]{2, 200}));
    System.out.println(jsInvoke.invokeFunction("execute", new Object[]{3, 200}));
}

执行结果

true
false
true
false

 

jexl3表达式引擎执行字符串表达式

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-jexl3</artifactId>
    <version>3.1</version>
</dependency>
private static final JexlEngine JEXL_ENGINE = new Engine();
// private static final JexlEngine JEXL_ENGINE = new JexlBuilder().strict(true).silent(false).cache(32).create();

public static void doExecute() throws Exception {
    JexlContext mapContext = new MapContext();
    mapContext.set("x", 1);
    mapContext.set("y", 1);
    Object evaluate = JEXL_ENGINE.createExpression("x+y").evaluate(mapContext);
    System.out.println(evaluate);

    String script = "if (company == 1) {\n" +
            "  return true;\n" +
            "} else if (company == 2 && amt > 100) {\n" +
            "  return true;\n" +
            "} else if (company == 3 && amt > 200) {\n" +
            "  return true;\n" +
            "} else {\n" +
            "  return false;\n" +
            "}\n";

    mapContext.set("company", 3);
    mapContext.set("amt", 201);
    Object execute = JEXL_ENGINE.createScript(script).execute(mapContext);
    System.out.println(execute);
	
	mapContext.set("out", System.out);
    mapContext.set("message", "hello world");
    JEXL_ENGINE.createExpression("out.println(message)").evaluate(mapContext);
}

执行结果

2
true
hello world

 

groovy规则引擎的使用

    <dependency>
        <groupId>org.codehaus.groovy</groupId>
        <artifactId>groovy</artifactId>
        <version>3.0.5</version>
    </dependency>
public static void main(String[] args) {
    String script = "" +
            "if (company == 1) {\n" +
            "  return true;\n" +
            "} else if (company == 2 && amt > 100) {\n" +
            "  return true;\n" +
            "} else if (company == 3 && amt > 200) {\n" +
            "  return true;\n" +
            "} else {\n" +
            "  return false;\n" +
            "}\n";
    Map<String, Object> env = Maps.newHashMap();
    env.put("x", 1);
    env.put("y", 2);
    Object result = execute("x+y", env);
    System.out.println(result);

    env.put("company", 3);
    env.put("amt", 201);
    Object execute = execute(script, env);
    System.out.println(execute);
}


public static Object execute(String scriptText, Map<String, Object> env) {
    Script script = new GroovyShell().parse(scriptText);
    script.setBinding(new Binding(env));
    return script.run();
}

运行结果

3
true
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jaemon

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值