You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java与GraalJS ScriptEngine变量交互问题及解决方法咨询

问题解答

1. 数组、List、Map绑定后无内容的原因

GraalJS默认把Java集合(数组、List、Map这类)以原生Java对象实例的形式暴露给JS环境,不会自动转换成JavaScript原生的Array或Object类型。JS的JSON.stringify和遍历逻辑只认对象的可枚举属性,但Java集合的元素、键值对不是以JS可枚举属性的形式存在,得通过Java的方法(比如get()、size())才能访问,所以直接用JS的方式操作就会得到空对象{}。

2. 解决方法

方法一:用GraalJS的Value类手动转换

借助GraalVM提供的org.graalvm.polyglot.Value类,把Java集合主动转成JS原生类型:

import org.graalvm.polyglot.Context;
import org.graalvm.polyglot.Value;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

// 初始化JS上下文
Context context = Context.create("js");

// 转换Java List为JS数组
List<String> javaList = Arrays.asList("a", "b", "c");
Value jsArray = context.asValue(javaList);
context.getBindings("js").putMember("jsList", jsArray);

// 转换Java Map为JS对象
Map<String, Integer> javaMap = Map.of("key1", 1, "key2", 2);
Value jsObj = context.asValue(javaMap);
context.getBindings("js").putMember("jsMap", jsObj);

// 转换Java数组为JS原生数组
int[] javaArray = new int[]{1,2,3};
Value jsNativeArray = context.asValue(javaArray);
context.getBindings("js").putMember("jsArray", jsNativeArray);

这样在JS里就能正常用JSON.stringify(jsList)或者遍历操作了。

方法二:配置Context开启自动类型转换

创建Context时设置js.java-handler-properties参数,让Java集合自动映射成JS原生类型:

import org.graalvm.polyglot.Context;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

Context context = Context.newBuilder("js")
        .option("js.java-handler-properties", "true")
        .build();

// 直接绑定Java集合即可
List<String> javaList = Arrays.asList("x", "y", "z");
context.getBindings("js").putMember("myList", javaList);

Map<String, String> javaMap = new HashMap<>();
javaMap.put("name", "test");
context.getBindings("js").putMember("myMap", javaMap);

这个配置会让GraalJS自动把Java的List转成JS数组、Map转成JS对象,Java数组也会转成JS原生数组。

方法三:手动JSON序列化(通用兼容方案)

如果不想依赖GraalVM的特定API,可以用Jackson这类JSON库先把Java集合序列化成JSON字符串,再在JS里解析:

import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

ObjectMapper mapper = new ObjectMapper();
List<String> javaList = Arrays.asList("foo", "bar");
String listJson = mapper.writeValueAsString(javaList);
context.getBindings("js").putMember("listJson", listJson);

Map<String, Integer> javaMap = Map.of("age", 20, "score", 90);
String mapJson = mapper.writeValueAsString(javaMap);
context.getBindings("js").putMember("mapJson", mapJson);

在JS中执行解析:

const myList = JSON.parse(listJson);
const myMap = JSON.parse(mapJson);

内容的提问来源于stack exchange,提问作者谢良基

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 04:28:27