Передача массива Java в JavaScript (через JSNI) и обратно в Java приводит к нулевому значению

Сценарий: у меня есть веб-приложение GWT, работающее в JavaFX WebView / WebEngine. Я могу без проблем передавать строки из GWT в JavaScript в JavaFX.

Проблема: при передаче таким же образом массива настраиваемых объектов, таких как Data [], результат на стороне JavaFX равен нулю.

Пример того, как выглядят данные:

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 ...
  }
}

Обратите внимание, что объект данных определен и доступен с обеих сторон.

Из документации 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 Framework, но мой объект Data не является допустимым bean-компонентом (я думаю, из-за отсутствия конструктора по умолчанию), и я не могу это изменить в настоящее время.

Я не использую длинные или длинные значения.

Я видел такие примеры:

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

Но насколько я могу судить, это просто переход от JavaScript к GWT через JSNI. Я пытаюсь пойти другим путем. Я также не смог найти такого примера для нескольких аргументов.

Я уверен, что здесь есть небольшая настройка, которую мне не хватает, но я еще не смог понять это. Пожалуйста, дайте мне знать, если вы увидите что-то, чего мне здесь не хватает.


person Splaktar    schedule 15.10.2013    source источник
comment
Перво-наперво: позволяет ли JavaFX передавать эти объекты таким образом? Сначала попробуйте использовать простой JS.   -  person Thomas Broyer    schedule 16.10.2013
comment
Спасибо, Томас. Это привело меня к следующему ответу: stackoverflow.com/questions/13194326/. Похоже, мне нужно будет сериализовать данные на сервере перед их отправкой в ​​GWT, а затем передать этот сериализованный JSON (String) в JavaFX. Наконец, JavaFX необходимо десериализовать.   -  person Splaktar    schedule 16.10.2013


Ответы (2)


непрозрачное значение, которое может быть передано только в код Java

Я думаю, это означает, что вы не можете передать массив Java в код JavaScript.

Согласитесь с jat. Раньше я предоставлял поддержку для подобных нужд, и мне приходилось самому сериализовать объекты. И вы можете передать несколько таких аргументов (типы аргументов приведены только для примера):

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

    // then call external non-static method
    [email protected]::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)
person alexp    schedule 16.10.2013
comment
Большое спасибо. Сериализация действительно сработала. Также спасибо за ответ на мой другой вопрос о формате нескольких непримитивных аргументов. - person Splaktar; 16.10.2013

Я не играл с JavaFX, но поскольку он работает на другой виртуальной машине и ничего не знает о протоколе GWT DevMode (например, объект Java завернут в объект JS, который в основном выполняет вызовы RPC для управления им), я довольно конечно, вам придется сериализовать все между GWT и JavaFX как строки и примитивы.

person jat    schedule 15.10.2013