Java用ScriptEngine解析脚本

12月 24th, 2010 25,840 留下评论 阅读评论

实习第一期的任务基本做完,从python和django的世界又回到了Java,当初来刚来百度的时候怎么也没想到居然还会用上Java。新的任务也很简单,不过正好学习了Java一个新的script包,可以用来解析脚本语法。

javax.script,始于JDK1.6,不过现在只有sun实现的javascript的解析器,难道是因为主要用来解析js语法所以归类到JEE的范畴?不过基本足够了,一般的用途主要是能解析通用的表达式就好,比如X >= 1(X作为参数传入)这样的表达式,也能利用js的函数语法,创造一个就像java的函数一样存在于内存中随时可以被调用的函数,更可以将js中的对象直接转换成java对象。

script包下最主要的是ScriptEngineManager、ScriptEngine、CompiledScript和Bindings 4个类或接口。

ScriptEngineManager是一个工厂的集合,可以通过name或tag的方式获取某个脚本的工厂并生成一个此脚本的ScriptEngine,目前只有javascript的工厂。通过工厂函数得到了ScriptEngine之后,就可以用这个对象来解析脚本字符串了,直接调用Object obj = ScriptEngine.eval(String script)即可,返回的obj为表达式的值,比如true、false或int值。

CompiledScript可以将ScriptEngine解析一段脚本的结果存起来,方便多次调用。只要将ScriptEngine用Compilable接口强制转换后,调用compile(String script)就返回了一个CompiledScript对象,要用的时候每次调用一下CompiledScript.eval()即可,一般适合用于js函数的使用。

Bindings的概念算稍微复杂点,我的理解Bindings是用来存放数据的容器。它有3个层级,为Global级、Engine级和Local级,前2者通过ScriptEngine.getBindings()获得,是唯一的对象,而Local Binding由ScriptEngine.createBindings()获得,很好理解,每次都产生一个新的。Global对应到工厂,Engine对应到ScriptEngine,向这2者里面加入任何数据或者编译后的脚本执行对象,在每一份新生成的Local Binding里面都会存在。

给个代码的例子,其中的functionScript可以从标准输入stdin或者配置文件等地方获得,这样就可以动态的控制Java代码的运行结果

1
2
3
4
5
6
7
8
9
10
11
try {
	ScriptEngine engine = new ScriptEngineManager().getEngineByName("javascript");
	Compilable compilable = (Compilable) engine;
	Bindings bindings = engine.createBindings(); //Local级别的Binding
	String script = "function add(op1,op2){return op1+op2} add(a, b)"; //定义函数并调用
	CompiledScript JSFunction = compilable.compile(script); //解析编译脚本函数
	bindings.put("a", 1);bindings.put("b", 2); //通过Bindings加入参数
	Object result = JSFunction.eval(bindings);
	System.out.println(result); //调用缓存着的脚本函数对象,Bindings作为参数容器传入
}
catch (ScriptException e) {}

另外还有一个ScriptContext的概念,这个可能很少用到吧,它是用来连接ScriptEngine和Bindings的工具。按照JDK的解释:该接口的实现类被用来连接ScriptEngine和宿主应用程序中的对象(如有范围的Bindings)。

Categories: Java, Javascript, 百度 标签:
  1. 匿名 | #沙发
    8月 30th, 2017 14:24

    :sad: :mrgreen: :idea: :grin:

  2. 匿名 | #板凳
    4月 26th, 2017 15:26

    :twisted: :twisted: :smile: :cool: :?:

  3. 4月 1st, 2016 17:41

    :shock: :razz: :grin: :evil: :?: :???: :???: :???: :???: :???: :???: :???: :???: :???: :???: :???: :???:

  4. tjumyk | #4
    7月 1st, 2013 08:37
  5. 1月 23rd, 2013 15:44

    var arrclass = new Array();
    var arrjob = new Array();

    arrclass.push(new Class(20000,”计算机-软件开发”));
    arrclass.push(new Class(30000,”计算机-网络/通讯”));
    arrclass.push(new Class(10000,”计算机-硬件开发”));
    arrclass.push(new Class(40000,”计算机-管理”));
    arrclass.push(new Class(50000,”计算机-品质管理/技术支持”));
    arrclass.push(new Class(320000,”电子/电器/半导体/仪器仪表”))

    JS中是这些数据,如何解析呢?

    • 呃…这么复杂涉及到OOP了恐怕没法解析吧…没尝试过诶…