繁体   English   中英

GraalVM - 将 Java 复杂对象暴露给 JavaScript

[英]GraalVM - Exposing Java complex objects to JavaScript

使用 GraalVM 将 Java 对象公开给 JavaScript,我使用ProxyObject来包装它们。 为此,我使用了ProxyObject.fromMap方法,如下所示:

ProxyObject exposedObject = ProxyObject.fromMap(objectMapper.convertValue(javaObject, Map.class));

这里, javaObject属于Object类,可以任意复杂。 此方法适用于javaObject直接成员,但不适用于成员本身是复杂对象。 例如,如果javaObject的成员之一恰好是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);

这是在 JavaScript 中访问exposedObject对象时发生的情况:

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 或者是否有支持的开箱即用的方法来实现这一点?

另外,如果我的方法需要改变,请告诉我。

正如 ProxyObject [1] 的 javadoc 所说:“要实现的接口以模仿包含成员的来宾语言对象。”。 这意味着,如果您希望 Java 对象在 JavaScript 中使用,就好像它是 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/

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM