1 概述
本文介紹在 Java 環境中執行 JavaScript 腳本的簡單使用,具體包含以下內容
- Java 8 中的內置 Nashorn Javascript 引擎介紹
- Rhino JavaScript 引擎介紹以及對 XML 的處理介紹
2 Java 8 中的內置 Nashorn Javascript 引擎介紹
Nashorn 是 Java 8 中內置的 JavaScript 引擎,無需加入任何依賴。
Nashorn 基本使用步驟如下
- new 出 ScriptEngineManager 對象
- 通過 ScriptEngineManager 對象中的 getEngineByName 方法獲取指定的 JavaScript 引擎,返回 ScriptEngine 對象
- Java 8 中的默認的 Javascript 引擎包括:[nashorn, Nashorn, js, JS, JavaScript, javascript, ECMAScript, ecmascript]
- 通過 ScriptEngine 對象的 eval 方法來執行 JavaScript 腳本。
2.1 通過 PrintWriter 對象獲取腳本中的 print 輸出
Javascript 腳本中沒有函數,沒有返回值,通過 print 輸出內容,這時需要通過 PrintWriter 獲取讀取腳本中的 print 輸出,具體如下
@Test
public void test_nashorn() {
try {
ScriptEngine engine = new ScriptEngineManager().getEngineByName("Nashorn");
ScriptContext scriptContext = engine.getContext();
StringWriter stringWriter = new StringWriter();
PrintWriter printWriter = new PrintWriter(stringWriter);
scriptContext.setWriter(printWriter);
String jsString = "var obj=JSON.parse('{\\\"data\\\":\\\"7155\\\",\\\"sign\\\":\\\"success\\\",\\\"message\\\":null}');print(obj.sign==\"success\");";
stringWriter = new StringWriter();
printWriter = new PrintWriter(stringWriter);
scriptContext.setWriter(printWriter);
engine.eval(jsString);
System.out.println(String.format("1 result = %s",stringWriter.toString()));
jsString = "var obj=JSON.parse('{\\\"data\\\":\\\"7157\\\",\\\"sign\\\":\\\"success\\\",\\\"message\\\":null}');print((function getData() { return obj.data;})())";
stringWriter = new StringWriter();
printWriter = new PrintWriter(stringWriter);
scriptContext.setWriter(printWriter);
engine.eval(jsString);
System.out.println(String.format("2 result = %s",stringWriter.toString()));
jsString = "var obj=JSON.parse('{\\\"data\\\":\\\"7157\\\",\\\"sign\\\":\\\"success\\\",\\\"message\\\":null}');print((function getData() { return obj.data;})())";
stringWriter = new StringWriter();
printWriter = new PrintWriter(stringWriter);
scriptContext.setWriter(printWriter);
engine.eval(jsString);
System.out.println(String.format("3 result = %s",stringWriter.toString()));
} catch (Exception e) {
e.printStackTrace();
}
}
2.2 獲取匿名函數的返回值
Javascript 腳本是一個匿名函數并且有返回值,通過 eval 函數可以直接
@Test
public void test_js_function_return() {
try {
ScriptEngine engine = new ScriptEngineManager().getEngineByName("Nashorn");
String jsFunction = "(function(){var obj=JSON.parse('{\\\"data\\\":\\\"7155\\\",\\\"sign\\\":\\\"success\\\",\\\"message\\\":null}');return obj.sign==\"success\"})();";
Boolean result = (Boolean) engine.eval(jsFunction);
System.out.println(result);
} catch (Exception e) {
e.printStackTrace();
}
}
2.3 調用 Javascript 腳本中指定的函數
Javascript 腳本中有變量,有多個函數,具體如下
@Test
public void test_invoke_js_function() {
try {
ScriptEngine engine = new ScriptEngineManager().getEngineByName("Nashorn");
/*
var obj = JSON.parse('{\"data\":\"7155\",\"sign\":\"success\",\"message\":null}');
function checkSign() {
return obj.sign == 'success'
}
function getData() {
return obj.data
}
function calculate(a, b) {
return a + b
}
*/
String jsFunction = "var obj=JSON.parse('{\\\"data\\\":\\\"7155\\\",\\\"sign\\\":\\\"success\\\",\\\"message\\\":null}');function checkSign(){return obj.sign=='success'}function getData(){return obj.data}function calculate(a,b){return a+b}";
engine.eval(jsFunction);
Invocable invocable = (Invocable) engine;
Object result = invocable.invokeFunction("checkSign", null);
System.out.println(result);
result = invocable.invokeFunction("getData", null);
System.out.println(result);
result = invocable.invokeFunction("calculate", 2, 5);
System.out.println(result);
} catch (Exception e) {
e.printStackTrace();
}
}
- 輸出如下
true
7155
7.0
2.4 讀取 Javascript 文件并執行
這種情況是讀取 Javascript 文件,并執行,具體如下
- src/test/resources/test.js
@Test
public void test_invoke_js_file() {
try {
ScriptEngine engine = new ScriptEngineManager().getEngineByName("Nashorn");
engine.eval(new FileReader(TestJSEngine.class.getResource("/test.js").getPath()));
Invocable invocable = (Invocable) engine;
Object result = invocable.invokeFunction("checkSign", null);
System.out.println(result);
result = invocable.invokeFunction("getData", null);
System.out.println(result);
result = invocable.invokeFunction("calculate", 2, 5);
System.out.println(result);
} catch (Exception e) {
e.printStackTrace();
}
}
文件內容和上面一樣。
3 Rhino JavaScript 引擎介紹
默認的 Nashorn 引擎是無法解析 xml 的,像 DOMParser 這樣的對象是瀏覽器內置的組件。
這里可以通過 Maven 依賴 Rhino 引擎來處理 xml。
- Rhino Maven 依賴如下
<dependency>
<groupId>cat.inspiracio</groupId>
<artifactId>rhino-js-engine</artifactId>
<version>1.7.10</version>
</dependency>
使用的步驟和其他 JavaScript 引擎一樣,引擎的名稱為 Rhino.
3.1 Rhino 對 xml 的解析
這里通過讀取文件的方式來加載和解析 JavaScript 腳本,腳本中是對一段 xml 的解析的過程。
- src/test/resources/xml.js 文件內容如下
print("----------------------------------------");
var e = new XML('<employees> <employee id="1"><name>Joe</name><age>20</age></employee> <employee id="2"><name>Sue</name><age>30</age></employee> </employees>');
// 獲取所有的員工
print("獲取所有的員工:\n" + e..name);
// 名字叫 Joe 的員工
print("名字叫 Joe 的員工:\n" + e.employee.(name == "Joe"));
// 員工的id 為 1 和 2
print("員工的id 為 1 和 2:\n" + e.employee.(@id == 1 || @id == 2));
// 員工的id 為 1
print("員工的id 為 1: " + e.employee.(@id == 1).name);
print("----------------------------------------");
- 執行如下
@Test
public void test_rhino_file_js() {
try {
ScriptEngine engine = new ScriptEngineManager().getEngineByName("rhino");
ScriptContext scriptContext = engine.getContext();
StringWriter stringWriter = new StringWriter();
PrintWriter printWriter = new PrintWriter(stringWriter);
scriptContext.setWriter(printWriter);
engine.eval(new FileReader(TestJSEngine.class.getResource("/xml.js").getPath()));
System.out.println(String.format("xml result = %s",stringWriter.toString() ));
} catch (Exception e) {
e.printStackTrace();
}
}
- 輸出如下
xml result = ----------------------------------------
All the employee names are:
<name>Joe</name>
<name>Sue</name>
The employee named Joe is:
<employee id="1">
<name>Joe</name>
<age>20</age>
</employee>
Employees with ids 1 & 2:
<employee id="1">
<name>Joe</name>
<age>20</age>
</employee>
<employee id="2">
<name>Sue</name>
<age>30</age>
</employee>
Name of the the employee with ID=1: Joe
----------------------------------------
3.2 測試
- xml 內容如下
<CCardProcessSyncResponse>
<RetCode>0</RetCode>
<Message>操作成功!</Message>
<RefundCycle />
<EpayRefundCycleMin>1</EpayRefundCycleMin>
<EpayRefundCycleMax>7</EpayRefundCycleMax>
<EpayRefundCycleUnitF />
</CCardProcessSyncResponse>
- 具體測試如下
@Test
public void test_rhino() {
try {
ScriptEngine engine = new ScriptEngineManager().getEngineByName("rhino");
String jsString = jsString = "var obj=new XML('<CCardProcessSyncResponse> <RetCode>0</RetCode> <Message>操作成功!</Message> <RefundCycle /> <EpayRefundCycleMin>1</EpayRefundCycleMin> <EpayRefundCycleMax>7</EpayRefundCycleMax> <EpayRefundCycleUnitF /> </CCardProcessSyncResponse>');print(obj.Message == '操作成功!');";
ScriptContext scriptContext = engine.getContext();
StringWriter stringWriter = new StringWriter();
PrintWriter printWriter = new PrintWriter(stringWriter);
scriptContext.setWriter(printWriter);
engine.eval(jsString);
System.out.println(String.format("xml result = %s",stringWriter.toString() ));
} catch (Exception e) {
e.printStackTrace();
}
}
上面的輸出結果如下
xml result = true
版權聲明:本文內容由互聯網用戶自發貢獻,該文觀點僅代表作者本人。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如發現本站有涉嫌抄襲侵權/違法違規的內容, 請發送郵件至 舉報,一經查實,本站將立刻刪除。
發表評論
請登錄后評論...
登錄后才能評論