JDK1.8中如何用ScriptEngine动态执行JS
jdk1.6开始就提供了动态脚本语言诸如JavaScript动态的支持。这无疑是一个很好的功能,毕竟Java的语法不是适合成为动态语言。而JDK通过执行JavaScript脚本可以弥补这一不足。这也符合“Java虚拟机不仅仅是Java一种语言的虚拟机“这一目标。
ScriptEngine功能强大,基本能实现笔者所能想到的Java与JavaScript交互的需求。而且十分的方便简洁。jdk1.8又对ScriptEngine接口进行了一定改变,因此,在jdk1.8能运行的代码,在1.6中可能会报错,反之亦然。
下面通过具体的代码讲解:
import java.util.Map;
import java.util.TreeMap;import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.SimpleBindings;import jdk.nashorn.api.scripting.ScriptObjectMirror;public class JSEngine {public static ScriptEngine engine;private static String str;//该函数测试Java获取JS变量值的能力public static void getJsValue() throws Exception{str = " var msg='hello'; "+ " var number = 123; "+ " var array=['A','B','C']; "+ " var json={ "+ " 'name':'pd', "+ " 'subjson':{ "+ " 'subname':'spd' "+ " ,'id':123 "+ " } "+ " }; ";//执行语句engine.eval(str);str="msg+=' world';number+=5";//再次执行engine.eval(str);//获取js变量msg(String类型)System.out.println(engine.get("msg"));//获取js变量msg(int类型)System.out.println(engine.get("number"));//获取js变量array(数组)ScriptObjectMirror array=(ScriptObjectMirror) engine.get("array");//getSlot(int index)函数用于获取下标为index的值System.out.println(array.getSlot(0));//获取js变量json(json类型)ScriptObjectMirror json=(ScriptObjectMirror) engine.get("json");//get(String key)函数用于键key的值System.out.println(json.get("name"));//获取js变量subjson(嵌套json类型)ScriptObjectMirror subjson=(ScriptObjectMirror)json.get("subjson");System.out.println(subjson.get("subname"));}//该函数测试Java与js对象public static void getObject() throws Exception{str = " var obj=new Object(); "+ " obj.info='hello world'; "+ " obj.getInfo=function(){ "+ " return this.info; "+ " }; ";engine.eval(str);//获取对象ScriptObjectMirror obj=(ScriptObjectMirror) engine.get("obj");//输出属性System.out.println(obj.get("info"));System.out.println(obj.get("getInfo"));str="obj.getInfo()";//执行方法System.out.println(engine.eval(str));}//java将变量导入js脚本public static void putValue() throws Exception{str="Math.pow(a,b)";Map<String, Object>input=new TreeMap<>();input.put("a",2);input.put("b",8);System.out.println(engine.eval(str,new SimpleBindings(input)));}//调用js函数public static void callJsFunction() throws Exception{engine.eval("function add (a, b) {return a+b; }");Invocable jsInvoke = (Invocable) engine;Object res = jsInvoke.invokeFunction("add", new Object[] { 10, 5 });System.out.println(res);}public static void main(String[] args) throws Exception {//获取js引擎实例ScriptEngineManager sem = new ScriptEngineManager();engine=sem.getEngineByName("javascript");getJsValue();getObject();putValue();callJsFunction();}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
是不是很有趣呢,注意的是ScriptObjectMirror类上市jdk1.8的类,该类对于先前版本的相应类进行了封装,使得代码很简单了。