最近在看js的书,书上有介绍两个服务端js,以前只听说过node.js,第一次听说Rhino.js,并且已经集成到了jdk1.6;看来还是见的少啊!
Rhino是一种用Java编写的javaScript解释器,能自动完成JavaScript原生类型到Java原生类型之间的相互转换,有了它,可以通过JavaScript脚本设置。查询Java属性,并调用java方法;
先上学习的代码:
package com.my.rhino;import java.io.FileReader;import java.util.List;import javax.script.Bindings;import javax.script.Compilable;import javax.script.CompiledScript;import javax.script.Invocable;import javax.script.ScriptContext;import javax.script.ScriptEngine;import javax.script.ScriptEngineFactory;import javax.script.ScriptEngineManager;import javax.script.ScriptException;public class RhinoDemo { public static void main(String[] args) { // create ScriptEngineManager ScriptEngineManager manager = new ScriptEngineManager(); ScriptEngine engine = manager.getEngineByName("js"); String script = "print ('hello nm')"; try { engine.eval(script); System.out.println(); } catch (ScriptException e) { e.printStackTrace(); } try { Double hour = (Double) engine.eval("var date = new Date(); date.getHours();"); String msg; if (hour < 10) { msg = "Good morning"; } else if (hour < 16) { msg = "Good afternoon"; } else if (hour < 20) { msg = "Good evening"; } else { msg = "Good night"; } System.out.println(hour); System.out.println(msg); } catch (ScriptException e) { System.err.println(e); } try { FileReader reader = new FileReader("src/com/my/rhino/file.js"); Double num = (Double) engine.eval(reader); System.out.println(num); reader.close(); } catch (Exception e) { e.printStackTrace(); } try { engine.put("a", 1); engine.put("b", 5); Bindings bindings = engine.getBindings(ScriptContext.ENGINE_SCOPE); Object a = bindings.get("a"); Object b = bindings.get("b"); System.out.println("a = " + a); System.out.println("b = " + b); FileReader reader = new FileReader("src/com/my/rhino/vars.js"); Double num = (Double) engine.eval(reader); System.out.println(num); reader.close(); reader = new FileReader("src/com/my/rhino/fun.js"); // engine.eval("function add (a, b) {c = a + b; return c; }"); engine.eval(reader); Invocable jsInvoke = (Invocable) engine; Object result1 = jsInvoke.invokeFunction("add", new Object[] { 10, 5 }); System.out.println(result1); Adder adder = jsInvoke.getInterface(Adder.class); int result2 = adder.add(10, 5); System.out.println(result2); Compilable jsCompile = (Compilable) engine; CompiledScript vscript = jsCompile.compile("function hi () {print ('ddddd !'); }; hi ();"); for (int i = 0; i < 5; i++) { vscript.eval(); } } catch (Exception e) { // TODO: handle exception } try { FileReader reader = new FileReader("src/com/my/rhino/java.js"); @SuppressWarnings("unchecked") Listnum = (List ) engine.eval(reader); System.out.println(); for (String word : num) { System.out.print(word); } reader.close(); } catch (Exception e) { e.printStackTrace(); } List factoryList = manager.getEngineFactories(); for (ScriptEngineFactory factory : factoryList) { System.out.println("====="); System.out.println(factory.getEngineName()); System.out.println(factory.getEngineVersion()); System.out.println(factory.getLanguageName()); System.out.println(factory.getLanguageVersion()); System.out.println(factory.getExtensions()); System.out.println(factory.getMimeTypes()); System.out.println(factory.getNames()); } }}
下面解析下:
1、创建一个script 引擎管理器并根据名称获取需要的js引擎;以下所有操作基于这两行代码;
// create ScriptEngineManager
ScriptEngineManager manager = new ScriptEngineManager(); // create a JavaScript engine ScriptEngine engine = manager.getEngineByName("js");引擎也许不止一个,可以通过以下代码输出查看;
ListfactoryList = manager.getEngineFactories(); for (ScriptEngineFactory factory : factoryList) { System.out.println("====="); System.out.println(factory.getEngineName()); System.out.println(factory.getEngineVersion()); System.out.println(factory.getLanguageName()); System.out.println(factory.getLanguageVersion()); System.out.println(factory.getExtensions()); System.out.println(factory.getMimeTypes()); System.out.println(factory.getNames()); }
获取支持的所有引擎的详细信息;我的机器输出如下:
Mozilla Rhino
1.7 release 3 PRERELEASEECMAScript1.8[js][application/javascript, application/ecmascript, text/javascript, text/ecmascript][js, rhino, JavaScript, javascript, ECMAScript, ecmascript]2、简单输出字符串:
String script = "print ('hello nm')"; try { engine.eval(script); System.out.println(); } catch (ScriptException e) { e.printStackTrace(); } console: hello nm
3、执行简单的js代码获取返回值:
try { Double hour = (Double) engine.eval("var date = new Date(); date.getHours();"); System.out.println(hour); } catch (ScriptException e) { System.err.println(e); } console输出当前时间的小时数: //13.0
4、执行js文件里面的语句,并获取返回值:
//java代码: try { FileReader reader = new FileReader("src/com/my/rhino/file.js"); Double num = (Double) engine.eval(reader); System.out.println(num); reader.close(); } catch (Exception e) { e.printStackTrace(); } console ---> 18.0
//file.js function add(a,b){ return a+b;}//add(10,8); result = add(10,8);//以上两行语句皆可实现
5、传递变量给js文件并执行js文件代码:
//java代码 engine.put("a", 1); engine.put("b", 5); Bindings bindings = engine.getBindings(ScriptContext.ENGINE_SCOPE); Object a = bindings.get("a"); Object b = bindings.get("b"); System.out.println("a = " + a); System.out.println("b = " + b); FileReader reader = new FileReader("src/com/my/rhino/vars.js"); Double num = (Double) engine.eval(reader); System.out.println(num); reader.close();
//vars.js m = a+5;n = b+6;d = a+b;
console---> 6.0 //只会返回最后一行的结果值
6、java调用js中的方法:
reader = new FileReader("src/com/my/rhino/file.js"); // engine.eval("function add (a, b) {c = a + b; return c; }"); engine.eval(reader); Invocable jsInvoke = (Invocable) engine; Object result1 = jsInvoke.invokeFunction("add", new Object[] { 10, 5 }); System.out.println(result1); //动态实现接口,从脚本引擎中得到Java Interface 的实例;也就是说,可以定义个一个Java接口,其实现是由脚本完成,函数名称必须相同; Adder adder = jsInvoke.getInterface(Adder.class); int result2 = adder.add(10, 5); System.out.println(result2);
package com.my.rhino;interface Adder { int add(int a, int b);}
console----->
15.0 15
7、编译执行
脚本引擎默认是解释执行的,如果需要反复执行脚本,可以使用它的可选接口Compilable来编译执行脚本,以获得更好的性能,示例代码如下:
Compilable jsCompile = (Compilable) engine; CompiledScript vscript = jsCompile.compile("function hi () {print ('ddddd !'); }; hi ();"); for (int i = 0; i < 5; i++) { vscript.eval(); }//其中js代码可以从js文件中加载
8、使用java中的对象:
try { FileReader reader = new FileReader("src/com/my/rhino/java.js"); @SuppressWarnings("unchecked") Listnum = (List ) engine.eval(reader); System.out.println(); for (String word : num) { System.out.print(word); } reader.close(); } catch (Exception e) { e.printStackTrace(); }
//java.js importPackage(java.util);//var list = java.util.ArrayList();var list = ArrayList();list.add('ni');list.add(' zai');list.add(' zuo');list.add(' sha');list;//var list = java.util.ArrayList();等价于importPackage(java.util); var list = ArrayList();
9、总结:
这都是很基本的,高级应用还需研究!