使用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()取絕對值

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