Spring boot 集成GraalVM JS引擎快速入门demo

本文介绍了GraalVM.js,一种能在JVM上运行Node.js应用的JavaScript引擎,探讨了其在SpringBoot项目中的应用,包括代码工程、本地和远程调用示例,以及Java与JavaScript的交互。
摘要由CSDN通过智能技术生成

一、GraalVM.js介绍

是一款 JavaScript 解释器/编译器,能够在 JVM 上运行 Node.js 应用;

主要应用场景

因为JS是动态语言,不需要编译,因此可以通过JS动态改变程序执行逻辑,比如:风控规则,服务编排等等

二、代码工程

pom.xml

 
 
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>springboot-demo</artifactId>
        <groupId>com.et</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>


    <artifactId>graalvm-js</artifactId>


    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>
    <dependencies>


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>


        <dependency>
            <groupId>org.graalvm.js</groupId>
            <artifactId>js-scriptengine</artifactId>
            <version>20.2.0</version>
        </dependency>
        <dependency>
            <groupId>org.graalvm.js</groupId>
            <artifactId>js</artifactId>
            <version>20.2.0</version>
        </dependency>


    </dependencies>


</project>

属性文件

 
 
server:
  port: 8088

启动类

 
 
package com.et.graalvm.js;


import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;


@SpringBootApplication
public class DemoApplication {


   public static void main(String[] args) {
      SpringApplication.run(DemoApplication.class, args);
   }
}

代码仓库

  • https://github.com/Harries/springboot-demo

三、测试

本地调用

 
 
package com.et.graalvm.js;


import org.junit.Test;


import javax.script.*;


/**
 * @author liuhaihua
 * @version 1.0
 * @ClassName com.et.graalvm.js.JSTest
 * @Description todo
 * @date 2024年03月07日 9:47
 */


public class JSTest {
    @Test
    public  void test10(){
        // 创建JavaScript引擎
        ScriptEngine jsEngine = new ScriptEngineManager().getEngineByName("js");
//        ScriptEngine jsEngine = new ScriptEngineManager().getEngineByExtension("js");
//        ScriptEngine jsEngine = new ScriptEngineManager().getEngineByMimeType("text/javascript");
        // 方式一,默认设置变量
        jsEngine.put("hello", "jack");
        // 方式二,使用binding设置变量
        SimpleBindings bindings = new SimpleBindings();
        bindings.put("hello","world");
        jsEngine.setBindings(bindings, ScriptContext.GLOBAL_SCOPE);
        // 方式三,使用Context设置变量
        ScriptContext scriptContext = jsEngine.getContext();
        scriptContext.setAttribute("hello", "polo", ScriptContext.ENGINE_SCOPE);
        try {
            // 方式一,直接调用
            jsEngine.eval("print(hello)");
            // 方式二,编译调用(需要重复调用,建议先编译后调用)
            if (jsEngine instanceof Compilable){
                CompiledScript compileScript = ((Compilable) jsEngine).compile("print(hello)");
                if (compileScript != null){
                    for (int i = 0; i < 10; i++) {
                        compileScript.eval();
                    }
                }
            }
            Invocable invocable = ((Invocable)jsEngine);
            // 方式三,使用JavaScript中的顶层方法
            jsEngine.eval("function greet(name) { print('Hello, ' + name); } ");
            invocable.invokeFunction("greet", "tom");
            // 方式四,使用某个对象的方法
            jsEngine.eval("var obj = { getGreeting: function(name){ return 'hello, ' + name; } } ");
            Object obj = jsEngine.get("obj");
            Object result = invocable.invokeMethod(obj, "getGreeting", "kitty");
            System.out.println(result);


        } catch (ScriptException | NoSuchMethodException e) {
            e.printStackTrace();
        }
    }
}

远程调用

 
 
package com.et.graalvm.js;


import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;


public class RemoteJSTest {
    public static void main(String[] args) throws IOException, ScriptException {
        URL jsUrl = new URL("https://example.com/script.js"); // js文件的URL
        URLConnection connection = jsUrl.openConnection();
        InputStream inputStream = connection.getInputStream(); // 获取js文件的流


        BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
        StringBuilder sb = new StringBuilder();
        String line;
        while ((line = reader.readLine()) != null) {
            sb.append(line).append("\n"); // 将js文件的内容存入StringBuilder
        }
        reader.close();
        inputStream.close();


        ScriptEngineManager engineManager = new ScriptEngineManager();
        ScriptEngine engine = engineManager.getEngineByName("nashorn"); // 获取Nashorn引擎
        String script = sb.toString(); // js文件的内容
        engine.eval(script); // 运行js文件


        Object result = engine.eval("hello()"); // 调用js文件中名为"hello"的函数
        System.out.println(result); // 输出结果
    }
}

四、引用

  • https://www.graalvm.org/reference-manual/js/JavaInteroperability/

  • https://github.com/graalvm/graaljs/blob/master/docs/user/JavaScriptCompatibility.md

  • http://www.liuhaihua.cn/archives/710296.html

  • 10
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是一个简单的 Spring Boot 集成 WebSocket 的 Demo。 首先,你需要在 `pom.xml` 文件中添加以下依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency> ``` 然后,在 Spring Boot 的启动类上添加 `@EnableWebSocket` 注解。 ```java @SpringBootApplication @EnableWebSocket public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } ``` 接下来,创建一个 Websocket 处理器(Handler)类,用来处理 WebSocket 消息的收发。 ```java @Component public class WebSocketHandler extends TextWebSocketHandler { private static final List<WebSocketSession> sessions = new CopyOnWriteArrayList<>(); @Override public void afterConnectionEstablished(WebSocketSession session) throws Exception { sessions.add(session); System.out.println("New session established: " + session.getId()); } @Override public void handleTextMessage(WebSocketSession session, TextMessage message) throws IOException { System.out.println("Received message: " + message.getPayload()); for (WebSocketSession webSocketSession : sessions) { if (webSocketSession.isOpen() && !session.getId().equals(webSocketSession.getId())) { webSocketSession.sendMessage(message); } } } @Override public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception { sessions.remove(session); System.out.println("Session closed: " + session.getId()); } } ``` 在上面的代码中,我们使用 `TextWebSocketHandler` 类来处理文本消息。当客户端连接上 WebSocket 服务器时,`afterConnectionEstablished` 方法会被调用;当客户端发送消息时,`handleTextMessage` 方法会被调用;当客户端断开连接时,`afterConnectionClosed` 方法会被调用。在 `afterConnectionEstablished` 方法中,我们将当前 WebSocket 会话添加到 `sessions` 集合中;在 `handleTextMessage` 方法中,我们将接收到的消息转发给其他客户端;在 `afterConnectionClosed` 方法中,我们将当前 WebSocket 会话从 `sessions` 集合中移除。 最后,我们需要定义一个 WebSocket 配置类,用来注册我们创建的 WebSocket 处理器。 ```java @Configuration @EnableWebSocket public class WebSocketConfig implements WebSocketConfigurer { @Autowired private WebSocketHandler webSocketHandler; @Override public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { registry.addHandler(webSocketHandler, "/websocket").setAllowedOrigins("*"); } } ``` 在上面的代码中,我们使用 `WebSocketConfigurer` 接口来配置 WebSocket。首先,我们注入了之前创建的 WebSocket 处理器 `WebSocketHandler`;然后,我们在 `registerWebSocketHandlers` 方法中,使用 `WebSocketHandlerRegistry` 注册了我们的 WebSocket 处理器,并指定了 WebSocket 的路径为 `/websocket`,允许跨域访问。 至此,一个简单的 Spring Boot 集成 WebSocket 的 Demo 就完成了。你可以在前端页面中使用 `WebSocket` 对象连接到 `/websocket` 路径,来实现 WebSocket 的消息收发。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值