javascript - GraalVM - 将 Java 复杂对象暴露给 JavaScript
问题描述
使用 GraalVM 将 Java 对象公开给 JavaScript,我ProxyObject
用来包装它们。为此,我使用ProxyObject.fromMap
如下方法:
ProxyObject exposedObject = ProxyObject.fromMap(objectMapper.convertValue(javaObject, Map.class));
在这里,javaObject
是Object
类的,可以任意复杂。此方法适用于 的直接成员javaObject
,但不适用于成员本身是复杂对象的情况。例如,如果其中一个成员javaObject
恰好是 a Map
,例如:
final Map<String, Object> source = new HashMap<>();
source.put("id", "1234567890");
final Map<String, Object> sourceComponent = ImmutableMap.of("key", "value");
source.put("complex", sourceComponent);
// assuming the source is any object
ProxyObject exposedObject = ProxyObject.fromMap(objectMapper.convertValue(source, Map.class));
// or knowing that source is in fact a map
ProxyObject exposedObject = ProxyObject.fromMap(source);
exposedObject
这是在 JavaScript 中访问时发生的情况:
exposedObject; // returns {complex: JavaObject[com.google.common.collect.SingletonImmutableBiMap], id: "1234567890"}
exposedObject.id; // returns 01234567890
exposedObject.complex; // returns {key=value}
exposedObject.complex.key; // returns undefined
所以我的问题是我们如何才能将任意复杂和深度的 java 对象完全暴露给 javascript。我们是否必须递归地遍历所有成员并将它们包装到ProxyObject
s 中?或者是否有支持的开箱即用的方法来实现这一点?
另外,如果我的方法需要改变,请告诉我。
解决方案
正如 ProxyObject [1] 的 javadoc 所说“要实现的接口以模仿包含成员的来宾语言对象。”。这意味着,如果您希望在 JavaScript 中使用 Java 对象,就好像它是 JavaScript 的原生对象,它需要是 ProxyObject。
另一方面,正如网站文档 [2] 所示,传递给 JavaScript 的 Java 对象仍然可以用作 Java 对象(即默认情况下它们不模仿 JS 对象)。这意味着您可以访问字段、调用方法等。网站文档显示了一个示例:
public static class MyClass {
public int id = 42;
public String text = "42";
public int[] arr = new int[]{1, 42, 3};
public Callable<Integer> ret42 = () -> 42;
}
public static void main(String[] args) {
try (Context context = Context.newBuilder()
.allowAllAccess(true)
.build()) {
context.getBindings("js").putMember("javaObj", new MyClass());
boolean valid = context.eval("js",
" javaObj.id == 42" +
" && javaObj.text == '42'" +
" && javaObj.arr[1] == 42" +
" && javaObj.ret42() == 42")
.asBoolean();
assert valid == true;
}
}
[1] https://www.graalvm.org/truffle/javadoc/org/graalvm/polyglot/proxy/ProxyObject.html
[2] https://www.graalvm.org/reference-manual/embed-languages/
推荐阅读
- javascript - 运算符'>'不能应用于Angular 8中的类型'void'和'number'
- html - 如何将 HTML div 中的数据提取到 Excel 中
- html - 无法使用 jinja2 将 Id 属性添加到 html 元素
- java - 没有 addSink 的 ScreenCapturerAndroid
- c++ - 如何忽略图像的透明区域
- java - 如何修复“不允许将明文 HTTP 流量传输到 x”
- python - 通过换行符拆分列将熊猫数据框分解为单独的行
- sql - 查找前 2 个日期点之间的天数
- php - Wordpress 自定义主题:插件不会加载或仅显示代码
- ruby - 从 Asana REST API 获取所有任务和子任务的列表