Java scripting工具包提供了java可以访问其他语言脚本的能力,脚本片段将会在运行时编译成中间代码(字节码),并能够被java scripting引擎调用。在某些场景下,很有用。
1. 简单调用
/** * simple,默认java.*包中的API已经倒入到engine中。你可以使用那些API * @throws Exception */ private static void invoke1() throws Exception{ ScriptEngineManager engineManager = new ScriptEngineManager(); ScriptEngine engine = engineManager.getEngineByName("javascript"); //根据“脚本语言名称”获取执行引擎,java本身默认只支持javascript,对于其他脚本,可以 //使用第三方包(apache bsf,不过不是很好用) //getEngineByName方法每次都会创建一个心的Engine对象 //java.lang包默认已经导入 String script = "var message = 'This is javascript.';println(message);var total = 2;"; engine.eval(script); Double total = (Double)engine.get("total"); System.out.println(total); }
2. 向JS脚本传递参数
/** * 向当前engine调用中put参数,并交给script * @throws Exception */ private static void invoke2() throws Exception{ ScriptEngineManager engineManager = new ScriptEngineManager(); ScriptEngine engine = engineManager.getEngineByName("javascript"); String script = "for(var i=0;i< times;i++) {println(i);}"; engine.put("times", 10); engine.eval(script); }
3. 在JS中使用java对象的方法或属性
private static void invoke3() throws Exception{ ScriptEngineManager engineManager = new ScriptEngineManager(); ScriptEngine engine = engineManager.getEngineByName("javascript"); String script = "println(string + ',length:' + string.length);"; engine.put("string", "javascript"); engine.eval(script); }
4. 显式的调用JS的function
private static void invoke4() throws Exception{ ScriptEngineManager engineManager = new ScriptEngineManager(); RhinoScriptEngine engine = (RhinoScriptEngine)engineManager.getEngineByName("javascript"); String script = "function hello(message){println(message);}"; engine.eval(script); engine.invokeFunction("hello", "javascript"); }
5. 调用JS方法并传递参数
/** * script方法调用 * @throws Exception */ private static void invoke5() throws Exception{ ScriptEngineManager engineManager = new ScriptEngineManager(); RhinoScriptEngine engine = (RhinoScriptEngine)engineManager.getEngineByName("javascript"); String script = "function hello(message){println(message);}"; engine.eval(script); engine.invokeFunction("hello", "javascript"); }
6. 通过JS创建Object,并在JAVA中使用(JS面向对象)
/** * 在script中使用对象,创建对象,并调用script对象的方法 * @throws Exception */ private static void invoke6() throws Exception{ ScriptEngineManager engineManager = new ScriptEngineManager(); RhinoScriptEngine engine = (RhinoScriptEngine)engineManager.getEngineByName("javascript"); //user是一个全局对象,和js一致 String script = "var user = new Object();" + "user.name='';" + "user.age=1;" + "user.toString = function(){println('Name:' + user.name + ',age' + user.age)};" + "user.init = function(name,age){user.name = name;user.age = age};"; engine.eval(script); Object user = engine.get("user"); engine.invokeMethod(user, "init", "zhangsan",32); engine.invokeMethod(user, "toString", null); }
7. JS与面向对象
/** * 调用script中的function,使用function返回的值 * @throws Exception */ private static void invoke7() throws Exception{ ScriptEngineManager engineManager = new ScriptEngineManager(); RhinoScriptEngine engine = (RhinoScriptEngine)engineManager.getEngineByName("javascript"); //API String script = "function create(name,age){var user = new Object();user.name= name;user.age = age; return user};" + "function toString(user){println('Name:' + user.name + ',age:' + user.age);};"; engine.eval(script); Object user = engine.invokeFunction("create", "zhangsan",32); engine.invokeFunction("toString", user); }
8. 在JS脚本中,引入JAVA API
/** * 外部API的倒入和使用 * @throws Exception */ private static void invoke8() throws Exception{ ScriptEngineManager engineManager = new ScriptEngineManager(); RhinoScriptEngine engine = (RhinoScriptEngine)engineManager.getEngineByName("javascript"); String script = "importClass(org.apache.commons.lang.time.DateFormatUtils);" + "println(java.lang.System.currentTimeMillis());"; engine.eval(script); }
9. 在JS中使用java object:API混合使用
/** * 将java对象与JS结合使用 * @throws Exception */ private static void invoke9() throws Exception{ ScriptEngineManager engineManager = new ScriptEngineManager(); RhinoScriptEngine engine = (RhinoScriptEngine)engineManager.getEngineByName("javascript"); String script = "importClass(com.test.script.ScriptingTestMain.User);function info(user){return user.info();}"; User user = new User("zhangsan",32); engine.eval(script); String info = (String)engine.invokeFunction("info", user); System.out.println(info); }
10. JS-function作为JAVA 接口的实现
/** * 让js作为java API的实现类 * @throws Exception */ private static void invoke10() throws Exception{ ScriptEngineManager engineManager = new ScriptEngineManager(); RhinoScriptEngine engine = (RhinoScriptEngine)engineManager.getEngineByName("javascript"); String script = "function run(){var i = 0;while(i<100){println(i);i++;}}"; engine.eval(script); Runnable runnable = engine.getInterface(Runnable.class); Thread thread = new Thread(runnable); thread.start(); }
11. Engine与binding使用:参数传递和context管理
/** * 使用binding传递参数,类似于engine.put * @throws Exception */ private static void invoke11() throws Exception{ ScriptEngineManager engineManager = new ScriptEngineManager(); RhinoScriptEngine engine = (RhinoScriptEngine)engineManager.getEngineByName("javascript"); String script = "i;println(message);println(i)"; //default:ENGINE_SCOPE Bindings bindings = engine.createBindings();//Map bindings.put("message", "javascript"); bindings.put("i", "10"); engine.eval(script,bindings);//binding被当前eval使用 }
12. 尝试使用Context来保存engine执行的结果或者保持变量传递
/** * 使用context保存对象,以便在外部被使用 * @throws Exception */ private static void invoke12() throws Exception{ ScriptEngineManager engineManager = new ScriptEngineManager(); RhinoScriptEngine engine = (RhinoScriptEngine)engineManager.getEngineByName("javascript"); String script = "println(message)"; // ScriptContext engineContext = new SimpleScriptContext(); engineContext.setAttribute("globalMessage", "globalMessage", ScriptContext.ENGINE_SCOPE); engine.setContext(engineContext); engine.put("message", "javascript"); engine.eval(script); //GLOBAL_SCOPE似乎对JS引擎有些问题。 String globalMessage = (String)engine.getContext().getAttribute("globalMessage",ScriptContext.ENGINE_SCOPE); engine.put("message", globalMessage); engine.eval(script); }