杰瑞科技汇

javascript使用java

我会从几个层面来详细解释“JavaScript使用Java”这件事:

javascript使用java-图1
(图片来源网络,侵删)
  1. 最直接的方式:在JavaScript代码中调用Java代码 (通过特定技术)
  2. 最常见的方式:在Java应用中嵌入和运行JavaScript (这是更主流的用法)
  3. 在Web开发中的协同工作 (前后端分离)
  4. 一些重要的历史和概念澄清

最直接的方式:在JavaScript中调用Java

这是你问题字面意义上的答案,要让JavaScript(通常是浏览器中的JS)能够调用Java代码,你需要一个“桥梁”或“胶水层”,因为浏览器本身不认识Java,它只认识JavaScript。

主要技术:Nashorn (已过时) 和 GraalVM

A. Nashorn (在Java 8中引入,Java 11中移除)

Nashorn是JDK(Java开发工具包)中的一个JavaScript引擎,它允许你在Java虚拟机上直接运行JavaScript代码,反过来,它也提供了在JavaScript中调用Java类和方法的能力。

工作原理: Nashorn将JavaScript代码编译成Java字节码,然后在JVM上执行,这使得JS可以无缝地访问Java的整个生态系统。

如何使用:

javascript使用java-图2
(图片来源网络,侵删)
  1. 启动Nashorn Shell:

    jjs
  2. 在JS中调用Java标准库:

    // 导入Java类
    var ArrayList = Java.type('java.util.ArrayList');
    // 创建Java对象
    var list = new ArrayList();
    // 调用Java方法
    list.add("Hello");
    list.add("from");
    list.add("JavaScript!");
    // 遍历Java集合
    for (var i = 0; i < list.size(); i++) {
        print(list.get(i));
    }

    输出:

    Hello
    from
    JavaScript!
  3. 在JS中调用自定义Java类: 假设你有一个Java文件 MyJavaClass.java:

    javascript使用java-图3
    (图片来源网络,侵删)
    // MyJavaClass.java
    public class MyJavaClass {
        public String sayHello(String name) {
            return "Hello, " + name + " from Java!";
        }
    }

    你可以在JS中这样调用:

    jjs MyJavaScript.js

    MyJavaScript.js 文件内容:

    // 加载编译好的Java类文件
    load("MyJavaClass.class");
    // 获取Java类类型
    var MyClass = Java.type('MyJavaClass');
    // 创建实例并调用方法
    var myInstance = new MyClass();
    var result = myInstance.sayHello("Nashorn User");
    print(result);

    输出:

    Hello, Nashorn User from Java!

注意: Nashorn已经在Java 11中被移除了,不再被推荐使用。

B. GraalVM (现代替代方案)

GraalVM是一个现代的高性能JVM实现,它包含了新的JavaScript引擎(名为Graal.js),并且是Nashorn的继任者,它比Nashorn更强大,性能更好,并且支持多种语言互操作。

如何使用: GraalVM的使用方式与Nashorn类似,但功能更强大,它不仅能让你在JS中调用Java,还能调用其他运行在GraalVM上的语言(如Python, Ruby, R等)。


最常见的方式:在Java应用中嵌入和运行JavaScript

这其实是更普遍、更有用的场景,很多Java应用(如服务器端程序、桌面应用)需要具备脚本能力,比如执行用户提供的动态逻辑、配置文件等,这时,在Java中嵌入一个JavaScript引擎就非常理想。

主要技术:

  • Nashorn (Java 8)
  • GraalVM.js (Java 11+)
  • 第三方库:如Rhino (Mozilla的JS引擎,常用于Android)

如何使用 (以GraalVM.js为例):

  1. 添加依赖: 如果你使用Maven,添加GraalVM的SDK依赖。

    <dependency>
        <groupId>org.graalvm.js</groupId>
        <artifactId>js</artifactId>
        <version>23.1.0</version> <!-- 使用最新版本 -->
    </dependency>
  2. 在Java中执行JS代码:

    import org.graalvm.js.scripting.JS;
    import javax.script.ScriptEngine;
    import javax.script.ScriptEngineManager;
    import javax.script.ScriptException;
    public class JavaRunJS {
        public static void main(String[] args) {
            // 获取JS引擎
            ScriptEngine engine = new ScriptEngineManager().getEngineByName("graal.js");
            if (engine == null) {
                System.out.println("Graal.js engine not found!");
                return;
            }
            try {
                // 执行简单的JS表达式
                engine.eval("var message = 'Hello from JavaScript inside Java!';");
                engine.eval("print(message);");
                // 执行一个JS函数
                engine.eval("function add(a, b) { return a + b; }");
                // 从Java调用JS函数
                Object result = engine.eval("add(10, 20);");
                System.out.println("Result from JS function: " + result); // 输出 30
            } catch (ScriptException e) {
                e.printStackTrace();
            }
        }
    }

高级用法:在Java和JS之间传递对象

GraalVM/Nashorn允许你传递Java对象给JS,JS可以像调用普通JS对象一样调用该对象的方法。

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
public class JavaObjectToJS {
    public static void main(String[] args) throws Exception {
        ScriptEngine engine = new ScriptEngineManager().getEngineByName("graal.js");
        // 创建一个Java对象
        MyJavaService service = new MyJavaService();
        // 将Java对象注入到JS的全局变量中
        engine.put("myService", service);
        // 执行JS代码,可以操作Java对象
        engine.eval("print('Calling Java method from JS...');");
        engine.eval("var result = myService.greet('GraalVM User');");
        engine.eval("print('Result: ' + result);");
    }
}
class MyJavaService {
    public String greet(String name) {
        return "Java says: Welcome, " + name + "!";
    }
}

输出:

Calling Java method from JS...
Result: Java says: Welcome, GraalVM User!

在Web开发中的协同工作 (前后端分离)

这是最广为人知的模式,虽然JavaScript和Java运行在不同的环境中,但它们通过API进行通信,共同构建一个完整的Web应用。

  • 前端: 使用HTML, CSS, JavaScript (以及React, Vue, Angular等框架) 构建用户界面,运行在用户的浏览器中。
  • 后端: 使用 Java (以及Spring Boot, Jakarta EE等框架) 构建服务器端应用,负责业务逻辑、数据库操作和API服务。

工作流程:

  1. 用户在浏览器中点击一个按钮。
  2. 前端的JavaScript代码向服务器发送一个HTTP请求(使用fetchaxios)。
  3. 后端的Java应用(如一个Spring Boot的@RestController)接收到这个请求。
  4. Java代码执行业务逻辑(比如查询数据库、处理数据)。
  5. Java应用将处理结果格式化为JSON或XML。
  6. Java应用将JSON数据作为HTTP响应返回给浏览器。
  7. 浏览器的JavaScript代码接收到这个JSON响应,然后动态地更新页面内容,展示给用户。

示例:

  • 前端 (JavaScript):

    async function fetchUserData() {
      try {
        const response = await fetch('https://my-java-api.com/users/123');
        const user = await response.json(); // 将JSON响应解析为JS对象
        console.log('User data:', user.name);
      } catch (error) {
        console.error('Error fetching user:', error);
      }
    }
    fetchUserData();
  • 后端 (Java - Spring Boot):

    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RestController;
    @RestController
    public class UserController {
        @GetMapping("/users/{id}")
        public User getUser(@PathVariable String id) {
            // 模拟从数据库获取数据
            User user = new User();
            user.setId(id);
            user.setName("John Doe");
            user.setEmail("john.doe@example.com");
            return user; // Spring Boot会自动将对象序列化为JSON
        }
    }
    class User {
        private String id;
        private String name;
        private String email;
        // Getters and Setters...
    }

历史和概念澄清

  • JavaScript vs. Java:

    • JavaScript 是一种轻量级的、解释型的脚本语言,主要用于Web浏览器,但现在也用于服务器端(Node.js)和桌面应用。
    • Java 是一种强类型的、编译型的面向对象编程语言,以其“一次编写,到处运行”(WORA)的跨平台能力而闻名,广泛用于企业级后端应用、安卓开发等。
    • 它们是两种完全不同的语言,只是名字有点像。
  • JVM (Java虚拟机):

    • 这是Java程序运行的环境,JVM负责将Java字节码转换为特定机器的指令来执行。
    • NashornGraalVM这样的技术,就是把JavaScript“翻译”成JVM能理解的字节码,从而让JS也能享受到JVM的平台无关性和优化。
场景 如何实现 核心技术 主要用途
JS调用Java 在JS环境中直接调用Java类和方法 GraalVM, Nashorn (过时) 在脚本环境中利用Java强大的库和生态。
Java调用JS 在Java应用中嵌入并执行JS脚本 GraalVM.js, Nashorn, Rhino 为Java应用增加动态脚本能力,如配置、插件等。
前后端协同 通过HTTP API通信 JavaScript (前端) + Java (后端) 构建现代化的全栈Web应用。

“JavaScript使用Java”这句话,根据上下文可以指代以上几种不同的技术实现,在现代开发中,在Java应用中嵌入GraalVM.js前后端通过API协同 是最主流和最实用的两种方式。

分享:
扫描分享到社交APP
上一篇
下一篇