杰瑞科技汇

java 使用javascript

我们来做一个核心区分

java 使用javascript-图1
(图片来源网络,侵删)
特性 Java JavaScript
类型系统 强类型、静态类型 弱类型、动态类型
运行环境 JVM (Java虚拟机) 浏览器、Node.js
编译/解释 编译为字节码,由JVM解释执行 解释执行 (或JIT编译)
主要用途 企业级后端应用、安卓App、大数据处理 网页前端、服务器端、桌面应用
关系 无直接关系,只是名字相似 最初是为了让Java在浏览器中运行而设计,后独立发展

我们来看如何在 Java 的世界里使用 JavaScript。


在服务器端执行 JavaScript 代码 (最常见)

这是最经典和最实用的场景,你可以在一个 Java 后端服务(如 Spring Boot)中嵌入一个 JavaScript 引擎,用来处理一些逻辑,

  • 配置文件解析:使用 JSON 或 JavaScript 对象来配置复杂的业务规则。
  • 规则引擎:将业务规则用 JavaScript 编写,存储在数据库或文件中,运行时动态加载和执行,实现业务逻辑与代码的分离。
  • 脚本化功能:为你的应用提供一个脚本接口,允许用户或开发者编写脚本来扩展功能。
  • 测试:用 JavaScript 编写测试用例来测试 Java 代码。

在 Java 中,执行 JavaScript 代码最标准、最现代的方式是使用 NashornGraalVM

使用 Nashorn (Java 8+ 内置)

Nashorn 是 Java 8 引入的 JavaScript 引擎,它允许在 JVM 上直接运行 JavaScript 代码,虽然从 Java 11 开始 Nashorn 已被标记为“废弃”,但在 Java 8 环境中它仍然是一个非常可靠的选择。

java 使用javascript-图2
(图片来源网络,侵删)

示例代码:

import javax.script.*;
public class NashornExample {
    public static void main(String[] args) throws ScriptException {
        // 1. 获取 ScriptEngineManager
        ScriptEngineManager manager = new ScriptEngineManager();
        // 2. 获取 Nashorn 引擎 (通过名称 "nashorn" 或 "javascript")
        ScriptEngine engine = manager.getEngineByName("nashorn");
        if (engine == null) {
            System.out.println("Nashorn engine not found!");
            return;
        }
        System.out.println("--- Nashorn Example ---");
        // 3. 执行简单的 JavaScript 表达式
        engine.eval("var name = 'World';");
        engine.eval("print('Hello, ' + name);"); // 使用 print 函数
        // 4. 从 Java 向 JavaScript 传递变量
        engine.put("user", "Alice");
        engine.eval("print('Welcome, ' + user);");
        // 5. 从 JavaScript 调用 Java 方法
        engine.eval("var list = new java.util.ArrayList();");
        engine.eval("list.add('Item 1');");
        engine.eval("list.add('Item 2');");
        @SuppressWarnings("unchecked")
        java.util.ArrayList<String> resultList = (java.util.ArrayList<String>) engine.get("list");
        System.out.println("List from JavaScript: " + resultList);
        // 6. 调用 Java 的静态方法
        engine.eval("var System = Java.type('java.lang.System'); System.out.println('Current time: ' + System.currentTimeMillis());");
    }
}

如何运行: 确保你使用的是 Java 8 或更高版本(但低于 Java 11),直接编译并运行即可。

使用 GraalVM (现代推荐)

GraalVM 是一个高性能的 JDK,它包含了一个名为 Graal.js 的新一代 JavaScript 引擎,它比 Nashorn 更快,支持更新的 ECMAScript 标准,并且与 Java 生态集成得更好,这是目前强烈推荐的方式。

步骤:

java 使用javascript-图3
(图片来源网络,侵删)
  1. 下载并使用 GraalVM:首先你需要下载 GraalVM JDK 并设置环境变量。
  2. 添加 Maven 依赖:在你的 Maven 项目中添加 jsjs-scriptengine 依赖。
<dependencies>
    <!-- GraalVM JavaScript Engine -->
    <dependency>
        <groupId>org.graalvm.js</groupId>
        <artifactId>js</artifactId>
        <version>23.1.0</version> <!-- 请使用最新的版本 -->
    </dependency>
    <dependency>
        <groupId>org.graalvm.js</groupId>
        <artifactId>js-scriptengine</artifactId>
        <version>23.1.0</version>
    </dependency>
</dependencies>

示例代码: GraalVM 的 API 与 Nashorn 兼容,所以上面的代码几乎可以原封不动地运行,只需要将 getEngineByName("nashorn") 改为 getEngineByName("graal.js")

// ... (ScriptEngineManager manager = new ScriptEngineManager();)
ScriptEngine engine = manager.getEngineByName("graal.js"); // 关键改动
// ... (其余代码与 Nashorn 示例完全相同)

GraalVM 的优势:

  • 性能卓越:使用 GraalVM 的即时编译器,性能远超 Nashorn。
  • ES6+ 支持:支持现代 JavaScript 语法。
  • Node.js 兼容性:可以运行部分 Node.js 应用。
  • 多语言:同一个 JVM 上可以无缝切换 JavaScript、Python、Ruby 等语言。

在浏览器中运行 (前端)

这是 JavaScript 的主战场,你不会在浏览器中直接“运行 Java 代码”,而是通过以下方式让 Java 和 JavaScript 交互:

Java Applet (已废弃)

这是最早的方式,允许在网页中嵌入一个由 Java 编写的小程序,但由于安全、性能和兼容性问题,Applet 已经被所有现代浏览器弃用。现在不应再使用此技术。

GWT (Google Web Toolkit)

GWT 是一个前端框架,允许你用 Java 语言编写前端代码,GWT 编译器会将其翻译成优化的 JavaScript 代码,在浏览器中运行,它主要用于构建复杂的企业级 Web 应用的前端。

特点:

  • 用 Java 编写前端:对 Java 开发者非常友好。
  • 类型安全:利用 Java 的强类型系统来减少前端错误。
  • RPC 支持:可以像调用本地 Java 方法一样调用后端服务。

通过 HTTP API 交互 (最现代、最灵活的方式)

这是目前最主流和推荐的方式,Java 后端(用 Spring Boot、Jakarta EE 或 Micronaut 框架构建)提供一个 RESTful API,JavaScript (在浏览器或 Node.js 中) 通过 fetchaxios 等 HTTP 客户端来调用这个 API。

工作流程:

  1. Java 后端:提供一个 HTTP 端点,POST /api/calculate
  2. JavaScript 前端:捕获用户输入,然后发送一个 HTTP 请求到该端点,通常以 JSON 格式发送数据。
  3. Java 后端:接收请求,处理业务逻辑(可能涉及数据库操作等),然后将结果以 JSON 格式返回。
  4. JavaScript 前端:接收 JSON 响应,并更新网页的 DOM(文档对象模型)来展示结果。

示例:

  • Java (Spring Boot) 后端控制器

    @RestController
    @RequestMapping("/api")
    public class HelloController {
        @PostMapping("/greet")
        public Map<String, String> greetUser(@RequestBody Map<String, String> payload) {
            String name = payload.get("name");
            Map<String, String> response = new HashMap<>();
            response.put("message", "Hello from Java, " + name + "!");
            return response;
        }
    }
  • JavaScript (浏览器) 前端

    async function callJavaApi() {
        const name = document.getElementById('nameInput').value;
        const response = await fetch('/api/greet', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify({ name: name }),
        });
        if (!response.ok) {
            throw new Error('Network response was not ok');
        }
        const data = await response.json();
        document.getElementById('result').innerText = data.message;
    }

在桌面应用中执行

如果你正在开发一个 Java 桌面应用(例如使用 JavaFX 或 Swing),你也可以在应用中嵌入 JavaScript 引擎(如 Nashorn 或 GraalVM)来增加动态脚本功能。

示例 (JavaFX + Nashorn): 你可以创建一个文本区域让用户输入 JavaScript 代码,然后点击按钮执行,并在另一个区域显示结果。

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javax.script.*;
public class JSScriptRunner extends Application {
    private ScriptEngine engine;
    private TextArea outputArea;
    @Override
    public void start(Stage primaryStage) {
        ScriptEngineManager manager = new ScriptEngineManager();
        engine = manager.getEngineByName("nashorn");
        outputArea = new TextArea();
        outputArea.setEditable(false);
        TextArea codeArea = new TextArea("print('Hello from Nashorn in JavaFX!');\n2 + 2;");
        Button runButton = new Button("Run Script");
        runButton.setOnAction(e -> {
            try {
                outputArea.setText(engine.eval(codeArea.getText()).toString());
            } catch (ScriptException ex) {
                outputArea.setText("Error: " + ex.getMessage());
            }
        });
        VBox root = new VBox(10, new Label("JavaScript Code:"), codeArea, runButton, new Label("Output:"), outputArea);
        Scene scene = new Scene(root, 500, 400);
        primaryStage.setTitle("JS Runner in JavaFX");
        primaryStage.setScene(scene);
        primaryStage.show();
    }
    public static void main(String[] args) {
        launch(args);
    }
}

总结与建议

场景 推荐技术 说明
服务器端执行 JS GraalVM 现代、高性能,是 Nashorn 的继任者,如果你使用 Java 8,Nashorn 也可以。
浏览器端交互 HTTP API (REST/GraphQL) 最灵活、最标准的方式,前后端完全解耦。
桌面应用脚本化 GraalVM / Nashorn 在 JavaFX/Swing 应用中提供动态脚本能力。
前端开发 GWT (特定场景) 如果团队是纯 Java 开发者且希望保持一致性,可以考虑。

  • 在 Java 程序里运行 JS 代码,用 GraalVM
  • 让网页上的 JS 和 Java 后端通信,用 HTTP API
  • 不要再尝试使用 Applet 或其他过时的技术。
分享:
扫描分享到社交APP
上一篇
下一篇