📅  最后修改于: 2023-12-03 15:21:52.833000             🧑  作者: Mango
有时候,Java 开发者需要在自己的应用或者系统中调用 JavaScript 来完成某些任务。在 Java 程序中调用 JavaScript 的方式有很多,本文将介绍几种常用的方法。
Java SE 6 中引入了 javax.script
包,通过该包可以在 Java 程序中执行 JavaScript、Python、Ruby 等脚本语言。ScriptEngineManager 是一个工厂类,用于创建 ScriptEngine 实例,可以通过它来调用 JavaScript。
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
public class CallJavaScript {
public static void main(String[] args) throws ScriptException {
// 创建 ScriptEngineManager 实例
ScriptEngineManager engineManager = new ScriptEngineManager();
// 获取 JavaScript 引擎实例
ScriptEngine engine = engineManager.getEngineByName("javascript");
// 执行 JavaScript 代码
engine.eval("var message = 'Hello, World!'; print(message);");
}
}
以上代码通过 ScriptEngineManager 获取 JavaScript 引擎实例,然后调用 eval()
方法执行 JavaScript 代码。eval()
方法的返回值是 JavaScript 代码计算的结果。
这种方式的优势在于可以在一个线程中调用多次 JavaScript,而不需要重新创建 ScriptEngine 实例。但是,如果要在多个线程中调用 JavaScript,就需要为每个线程单独创建 ScriptEngine 实例。
在 JDK 8 中,替代 Rhino 引擎的 Nashorn 引擎被引入,性能更好,同时支持 ECMAScript 6 和 7。使用 Nashorn 引擎可以通过以下方式来调用 JavaScript。
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
public class CallJavaScript {
public static void main(String[] args) throws ScriptException, NoSuchMethodException {
ScriptEngineManager engineManager = new ScriptEngineManager();
ScriptEngine engine = engineManager.getEngineByName("nashorn");
String script = "var obj = { " +
" message: 'Hello, World!', " +
" hello: function(name) { " +
" print(this.message + ' My name is ' + name); " +
" } " +
"};";
engine.eval(script);
// 转换为 Invocable 对象
Invocable invocable = (Invocable) engine;
// 调用 JavaScript 函数
invocable.invokeMethod(engine.get("obj"), "hello", "Java");
}
}
以上代码中,我们首先定义了一个 JavaScript 对象 obj
,该对象有一个属性 message
和一个方法 hello
,该方法接受一个参数 name
并打印一条信息。通过 Invocable
接口的 invokeMethod()
方法可以调用 JavaScript 对象的方法并传入参数。
JavaFX 中内置了一个基于 WebKit 的浏览器引擎 JavaX WebEngine,我们可以通过它来加载 JavaScript 文件并调用其中的方法。
import javafx.application.Application;
import javafx.concurrent.Worker;
import javafx.scene.Scene;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
import netscape.javascript.JSObject;
public class CallJavaScript extends Application {
@Override
public void start(Stage primaryStage) {
WebView webView = new WebView();
WebEngine webEngine = webView.getEngine();
// 加载 JavaScript 文件
webEngine.load(getClass().getResource("/path/to/javascript.js").toExternalForm());
webEngine.getLoadWorker().stateProperty().addListener((observable, oldValue, newValue) -> {
if (newValue == Worker.State.SUCCEEDED) {
// 获取 JavaScript 的全局对象
JSObject jsObject = (JSObject) webEngine.executeScript("window");
// 调用 JavaScript 对象的方法
jsObject.call("alert", "Hello, World!");
}
});
Scene scene = new Scene(webView, 800, 600);
primaryStage.setScene(scene);
primaryStage.show();
}
}
以上代码中,我们创建了一个 JavaFX 的应用,加载指定路径的 JavaScript 文件并在加载完成后获取 JavaScript 的全局对象并调用其中的方法(alert)。
以上介绍了三种 Java 调用 JavaScript 的方式,开发者可以根据实际需求来选择合适的方式。ScriptEngineManager 是最常用的调用方式,Nashorn 引擎可以支持更高的 JavaScript 版本,并提供了更好的性能,JavaX WebEngine 可以对整个页面的 JavaScript 进行操作。