Java知识点总结(动态执行JS代码 )
@(Java知识点总结)[Java, 动态字节码操作]
JDK6.0之后提供了脚本引擎功能,让我们可以执行某些脚本语言,特别是javascript(javascript是一门解释性语言,动态性非常好)。
让JAVA的动态性得到更充分的体现,某些时候可以更加灵活的应对需求的变化。
脚本引擎介绍:
- 使得 Java 应用程序可以通过一套固定的 接口与各种脚本引擎 交互,从而达到在 Java 平台上调用各种脚本语言的目的 。
- Java 脚本 API 是连通 Java 平台和脚本语言 的 桥梁 。
- 可以把一些复杂异变的业务逻辑交给脚本语言处理,这又大大提高了开发效率。
Java 脚本 API 为开发者提供了如下功能:
获取脚本程序输入,通过脚本引擎运行脚本并返回运行结果,这是最核心的接口。
- 注意是:接口。 Java可以使用各种不同的实现,从而通用的调用 js 、 groovy 、 python 等脚本。
- 通过 脚本引擎 的运行上下文在脚本和 Java 平台间交换数据。
- 通过 Java 应用程序调用脚本函数。
JS脚本引擎Rhino
Rhino 是一种使用 Java 语言编写的 JavaScript 的开源实现,原先由Mozilla开发,现在被集成进入JDK 6.0。
官方首页
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.net.URL;
import java.util.List;
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
public class Test09 {
// 定义变量,存储到引擎上下文中
private static void test1(ScriptEngine engine) {
engine.put("msg", "张三是个好学生");
System.out.println(engine.get("msg")); // 获取变量的值
try {
engine.eval("msg='java是门好用的语言';"); // 修改变量的值
} catch (ScriptException e1) {
e1.printStackTrace();
}
System.out.println(engine.get("msg"));
}
// 定义一个对象
private static void test2(ScriptEngine engine) {
String str = "var user = {name:'张三',age:18,subjects:['计算机','英语']};";
str += "println(user.name);";
try {
engine.eval(str);
} catch (ScriptException e) {
e.printStackTrace();
}
}
// 定义一个函数
private static void test3(ScriptEngine engine) {
try {
engine.eval("function add(a,b){var sum = a+b;return sum;}");
} catch (ScriptException e) {
e.printStackTrace();
}
try {
// 取得调用接口
Invocable jsInvoke = (Invocable) engine;
// 执行脚本中定义的方法
Object result = jsInvoke.invokeFunction("add", new Object[] { 13, 20 });
System.out.println(result);
} catch (NoSuchMethodException | ScriptException e) {
e.printStackTrace();
}
}
// 导入其他java包,使用其他包中的java类
private static void test4(ScriptEngine engine) {
String jsCode = "importPackage(java.util); var list = Arrays.asList([\"浙江大学\",\"清华大学\",\"北京大学\"]); ";
try {
engine.eval(jsCode);
} catch (ScriptException e) {
e.printStackTrace();
}
List<String> list2 = (List<String>) engine.get("list");
for (String temp : list2) {
System.out.println(temp);
}
}
//执行一个js文件(我们将a.js至于项目的src下即可)
private static void test5(ScriptEngine engine) {
URL is = Test09.class.getClassLoader().getResource("a.js");
Reader r= null;
try {
r = new FileReader(is.getPath());
engine.eval(r);
} catch (FileNotFoundException | ScriptException e) {
e.printStackTrace();
}finally {
try {
r.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
// 获得脚本引擎
ScriptEngineManager sem = new ScriptEngineManager();
ScriptEngine engine = sem.getEngineByName("javascript");
test1(engine);
test2(engine); // java 8 出现异常:Caused by: <eval>:1 ReferenceError: "println" is not defined
test3(engine);
test4(engine); // java 8出现异常:Caused by: <eval>:1 ReferenceError: "importPackage" is not defined
test5(engine);
}
}