JAVA使用ScriptEngine 解析脚本

来源:互联网 发布:mac无法存储屏幕快照 编辑:程序博客网 时间:2024/06/05 07:19

前言

最近做一个功能需要把一个数学公式保存到数据库,然后通过java读取数学公式,传入参数进行计算,发现了java中的javax.script,它开始存在于JDK1.6,它可以解析通用的表达式,如三目,还可以利用js函数语法,创造一个就像java的函数一样存在于内存中随时可以被调用的函数,更可以将js中的对象直接转换成java对象。

script包

最主要的几个类和接口为:ScriptEngineManager,ScriptEngine,CompiledScript和Bindings

  • ScriptEngineManager:是一个工厂的集合,可以通过name或者tag的方式获取某一个脚本的工厂,并且生成一个脚本的ScriptEngine.
ScriptEngine engine=new ScriptEngineManager().getEngineByName("JavaScript");
  • ScriptEngine:是一个脚本引擎,包含一些操作方法,eval,createBindings,setBindings
engine.eval(option); //option:"10+((D-parseInt(D/28)*28)/7+1)*10";

option 可以是一段js代码,函数,函数传参需要调用 engine.createBindings获得bindings,bindings.put(key,value)来传入参数

  • CompliedScript: engine 实现该接口,可以将ScriptEngine解析一段脚本的结果存起来,方便多次调用,需要将engine向上转换
Compilable compilable=(Compilable) engine;CompiledScript JSFunction=compilable.compile(option); //解析编译脚本函数Bindings bindings=engine.createBindings();bindings.put(key,value);JSFunction.eval(bingdings);
  • Bindings:用来存放数据的容器,它有3个层级,为Global级、Engine级和Local级,前2者通过ScriptEngine.getBindings()获得,是唯一的对象,而Local Binding由ScriptEngine.createBindings()获得,很好理解,每次都产生一个新的。Global对应到工厂,Engine对应到ScriptEngine,向这2者里面加入任何数据或者编译后的脚本执行对象,在每一份新生成的Local Binding里面都会存在。

Demo

        String option="function getNum(num){if(num%7==0){ return 5+5*(parseInt(5*(num-parseInt(num/29)*28)/28)+1)}else{return 5;}} getNum(num)"        -------------------------------        try{            Compilable compilable = (Compilable) engine;            Bindings bindings = engine.createBindings(); //Local级别的Binding            CompiledScript JSFunction = compilable.compile(option); //解析编译脚本函数            for(Map.Entry<String,Object> entry:map.entrySet()){                bindings.put(entry.getKey(),entry.getValue());            }            Object result=JSFunction.eval(bindings);            System.out.println(result);            return (int)Double.parseDouble(result.toString());        }catch (ScriptException e) {            e.printStackTrace();        }
原创粉丝点击