Передача массива 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 в виде строк и примитивов.