📜  从 java 调用 javascript - Javascript (1)

📅  最后修改于: 2023-12-03 15:21:52.833000             🧑  作者: Mango

从 Java 调用 JavaScript

有时候,Java 开发者需要在自己的应用或者系统中调用 JavaScript 来完成某些任务。在 Java 程序中调用 JavaScript 的方式有很多,本文将介绍几种常用的方法。

使用 ScriptEngineManager

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 实例。

使用 Nashorn 引擎

在 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 对象的方法并传入参数。

使用 JavaX WebEngine

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 进行操作。