【问题标题】:How to cast a return value from javascript to java in GWT JSNI?如何在 GWT JSNI 中将返回值从 javascript 转换为 java?
【发布时间】:2020-01-11 03:17:48
【问题描述】:

JSNI方法不接受任何参数,而是返回一个Java Object类型:

 public static native String nativeJSFuncGwt() /*-{
        $wnd.console.log($wnd.someJSFunc());
        return "" + $wnd.someJSFunc() + "" ;
    }-*/;


//someJSFunc returns { abc:xcv, def:asd}

我可以看到在 javascript 控制台中打印的值,但 java 端无法理解转换。

是不是因为本机方法不接受任何参数?

String tokenFromNativeJS = nativeJSFuncGwt(); // String value is null 

GWT 中的文档也不够清晰。

【问题讨论】:

    标签: java gwt jsni


    【解决方案1】:

    由于 GWT 版本(2.4)的限制,我在这里发布了最终工作的内容

    来自 GWT 文档:

    传出 Java 类型:

    任何其他 Java 对象(包括数组)

    必须通过什么:

    必须源自 Java 的正确类型的 Java 对象 代码; Java 对象不能在 JavaScript 中“凭空”构造

    我的修改代码如下:

    public static native MyObject nativeJSFuncGwt(MyObject obj) /*-{
    
       var xyz = $wnd.someJsFunc();
    
       obj.@package.name::setter1(Ljava/lang/String;)(xyz);
    
       return obj;
    
     }-*/;
    

    我希望文档可以更清楚。

    【讨论】:

      【解决方案2】:

      第一步,避免使用 JSNI,你最好定义一个提供相同 API 访问的 JsInterop 方法。 JSNI 仍然可以在 GWT2 中工作,但 JsInterop 是 GWT3 的前进方向,并且通常更容易读写。这看起来像这样:

      @JsMethod(name = "someJSFunc", namespace = JsPackage.GLOBAL)
      public static native String someJSFunc();
      

      第二步,定义一个适合你预期的JS返回值的Java类型。这将适用于 JSNI 或 JsInterop。在 JSNI 中,您将创建一个 JavaScriptObject 子类,并提供访问字段的方法(有关更多详细信息,请参阅http://www.gwtproject.org/doc/latest/DevGuideCodingBasicsJSNI.html 和其他文档,但按照第一步,我不会在这里深入探讨)。对于您的示例对象,这在 JsInterop 中如下所示:

      @JsType(isNative = true, name = "Object", namespace = JsPackage.GLOBAL)
      public class SomeReturnObject {
          public String abc;
          public double def;
      }
      

      显然,将字段名称和类型替换为您自己项目中合适的任何内容。给这个新类型加上占位符名称,这就是你的全局 someJsFunc 的样子:

      @JsMethod(name = "someJSFunc", namespace = JsPackage.GLOBAL)
      public static native SomeReturnObject someJSFunc();
      

      您可以像在普通 Java 中所期望的那样使用它——不再需要编写 JSNI:

      SomeReturnObject object = someJSFunc();
      DomGlobal.console.log(object.abc + ": " + object.def);
      

      【讨论】:

      • 我们有一个使用 gwt 2.4.0 的旧代码库,无法升级到新版本。
      • 只要您不需要支持过去 8 年发布的任何浏览器,那应该会很好用。在这种情况下,您需要创建一个 JavaScriptObject 子类,并添加适当的 getter 方法来读取这些 abc/def 属性。对于此类遗留代码,以stackoverflow.com/a/15497221/860630 为例,但在 2019 年,这不是新问题的正确答案。
      • 这实际上是我第一次看到关于如何使用 Jsinterop 实现某事的漂亮、简单、易懂的解释。我总是阅读 use Jsinterop 但我找不到任何关于它的文档。我认为gwtproject.org 上什至没有提到它
      • @Knarf 当我链​​接了 JSNI 页面时,还有一个 JsInterop 页面,它通过简短的示例讨论了其中的一些内容:gwtproject.org/doc/latest/DevGuideCodingBasicsJsInterop.html。我在这样的 Q/A 中看到的主要力量是我们从一个特定的问题开始并解决它,而不是必须笼统地描述整个工具包可以做什么——更多好的问题会带来更有帮助的答案!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多