最近在看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") List<String> num = (List<String>) engine.eval(reader); System.out.println(); for (String word : num) { System.out.print(word); } reader.close(); } catch (Exception e) { e.printStackTrace(); } List<ScriptEngineFactory> 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");
引擎也许不止一个,可以通过以下代码输出查看;
List<ScriptEngineFactory> 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()); }
获取支持的所有引擎的详细信息;我的机器输出如下:
Mozilla Rhino
1.7 release 3 PRERELEASE
ECMAScript
1.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 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") List<String> num = (List<String>) 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、总结:
这都是很基本的,高级应用还需研究!