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

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

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

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

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, но последний шаг - это то, что терпит неудачу.

Я провел последние несколько часов, изучая переполнение стека, 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. Я пытаюсь пойти другим путем. Я также не мог найти пример этого для нескольких аргументов.

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

2 ответа

Решение

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

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

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

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)

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

Другие вопросы по тегам