使用ScriptEngine实现js算法

有一个需求让我们规定算法,然后传入参数自动得出结果,我开始找能把字符串转化为算式的工具,然后让我发现了一个神奇的东西

import javax.script.Bindings;
import javax.script.Compilable;
import javax.script.CompiledScript;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


public class ScriptEngineUtils {
    private static Logger logger = LoggerFactory.getLogger(ScriptEngineUtils.class);
    private static ScriptEngine engine;
    private static Compilable compilable;
    static {
        engine = new ScriptEngineManager().getEngineByName("javascript");
        compilable = (Compilable) engine;
    }
    public static String executeScript(String script, Map<String, Object> map) {
        Bindings bindings = engine.createBindings();
        CompiledScript JSFunction = null; //解析编译脚本函数
        try {
            JSFunction = compilable.compile(script);
            bindings.putAll(map);
            Object result = JSFunction.eval(bindings);
            return String.valueOf(result);
        } catch (ScriptException e) {
            logger.error(e.getMessage(), e);
        }
        return null;
    }
    public static void main(String[] args) throws ParseException {
        MachineModel machine = new MachineModel();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date now = new Date();
        machine.setNextMaintainDate(sdf.parse("2019-5-12"));
        String script = "machine.nextMaintainDate.time - now.time"; //可以用js的方式调用对象的属性
        Map<String, Object> map = new HashMap<>();
        map.put("machine", machine);
        map.put("now", now);
        System.out.println(executeScript(script, map));
        script = "Math.abs(10-20)";//可以使用js自带的函数
        System.out.println(executeScript(script, map));
        script = "a=222;b=123;a+b;";//甚至可以写js代码,会返回最后一个代码的返回值
        System.out.println(executeScript(script, map)); 
        script = "function add(a,b) {return a+b};add(20,10)"; //可以定义函数
        System.out.println(executeScript(script, map)); 
        script = "var sdf = new java.text.SimpleDateFormat('yyyy-MM-dd');sdf.format(machine.nextMaintainDate)";//可以调用java类的方法
        System.out.println(executeScript(script, map)); 
    }
}

可以解析js脚本,并且把参数传进去,然后就可以使用js的语法来使用了,非常灵活,传入对象还能使用object.param和object["param"]。还能使用js的常用方法,比如Math.abs()取绝对值

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章