Java scripting工具包提供了java可以访问其他语言脚本的能力,脚本片段将会在运行时编译成中间代码(字节码),并能够被java scripting引擎调用。在某些场景下,很有用。在javax.script包中有很多的类,但这些类中最主要的是ScriptEngineManager。
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", "html580",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", "html580",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("html580",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);
}