【问题标题】:Passing Java Array into JavaScript (via JSNI) and back out to Java results in null value将 Java 数组传递到 JavaScript(通过 JSNI)并返回到 Java 会导致空值
【发布时间】:2013-10-15 22:30:16
【问题描述】:

场景:我有一个在 JavaFX WebView/WebEngine 中运行的 GWT Web 应用程序。我能够毫无问题地将字符串从 GWT 传递到 JavaScript 到 JavaFX。

问题:当以相同方式传递自定义对象数组(如 Data[])时,JavaFX 端的结果为 null。

数据外观示例:

public class Data extends Serializable
{
  char[] name;
  int code;
  short bar;
}

以下是将数据发送到 JavaScript 的代码:

public static native void doNativeStuff(String id, Data[] data) /*-{
  $wnd.javaInterface.doStuff(id, data);
}-*/;

我已经在调试器中验证了传入的 Java 对象填充了数据并且看起来不错。

现在在 JavaFX 方面,我有以下代码将 javaInterface 添加到页面:

JSObject win = (JSObject) engine.executeScript("window");
win.setMember("javaInterface", new JavaInterface());

我知道这行得通,因为我将它用于仅传递字符串的其他方法,并且它们工作得很好。

public void doStuff(String id, Data[] data)
{
  // Right here, id == "validId" and data == null
  if (data != null)
  {
    ... do what is needed ...
  }
}

请注意,Data 对象已定义并可在两侧访问。

来自 GWT 文档:

Incoming Java type    How it appears to JavaScript code
Java array            opaque value that can only be passed back into Java code

我根本没有在 JavaScript 中接触它,我只是从 Java->JavaScript->Java 传递它,但最后一步似乎是失败的。

过去几个小时我一直在搜索 Stack Overflow、Google、GWT 组、gwtproject.org 等。但大多数示例只显示一个参数被传递,几乎没有一个显示 Java 数组用过。

我宁愿只是传递对象,而不是从 JSON 中转到->,但出于绝望,我确实尝试过。我尝试使用 GSON,但它在 GWT 客户端上不起作用。我尝试使用 GWT AutoBean 框架,但我的 Data 对象不是有效的 bean(我认为是因为没有默认构造函数),目前我无法更改它。

我没有使用任何 Long 或 long 值。

我见过这样的例子:

@com.google.gwt.examples.JSNIExample::staticFoo(Ljava/lang/String;)(s);

但据我所知,这只是为了通过 JSNI 从 JavaScript 到 GWT。我正试图走另一条路。对于多个参数,我也找不到这样的示例。

我确定这里只是缺少一个小调整,但我还没有弄清楚。如果您看到我在这里遗漏的东西,请告诉我。

【问题讨论】:

  • 第一件事:JavaFX 是否允许您以这种方式传递这些对象?首先尝试使用纯 JS。
  • 谢谢托马斯。尝试一下,我得到了以下答案:stackoverflow.com/questions/13194326/…。看起来我需要在将服务器上的数据发送到 GWT 之前对其进行序列化,然后将该序列化的 JSON(字符串)传递给 JavaFX。最后,JavaFX 需要反序列化它。

标签: gwt webview javafx-2 jsni javafx-webengine


【解决方案1】:

只能传递回 Java 代码的不透明值

我认为这意味着您不能将 Java 数组传递给 JavaScript 代码。

同意jat。我曾经为类似的需求提供支持,我不得不自己序列化对象。 您可以像这样传递多个参数(仅给出参数类型):

private native void doJSAction(MyClass handler)/*-{
    // do smth in JS

    // then call external non-static method
    handler.@com.myclient.helper.MyClass::doMyAction(Lcom/google/gwt/core/client/JavaScriptObject;Ljava/lang/String;Lcom/myclient/helper/MyClass;II)(jsNativeSmth, myString, handler, intA, intB);
}-*/;

其中doMyAction 类似于以下内容:

void doMyAction(JavaScriptObject jsObject, String s, MyClass instance, int a, int b)

【讨论】:

  • 非常感谢。序列化确实有效。也感谢您回答我关于多个非原始参数格式的其他问题。
【解决方案2】:

我没有玩过 JavaFX,但是因为它在不同的 VM 中运行,并且对 GWT DevMode 协议一无所知(例如,Java 对象被包装在一个基本上通过 RPC 调用来操作它的 JS 对象中),我很确定您将不得不将 GWT 和 JavaFX 之间的所有内容序列化为字符串和原语。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-05-30
    • 2016-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-05
    相关资源
    最近更新 更多