Предаването на Java Array в 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 ...
  }
}

Обърнете внимание, че обектът 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 Array.

Бих предпочел просто да прекарам обекта, вместо да отида до->от 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 (низ) на JavaFX. Накрая JavaFX ще трябва да го десериализира.   -  person Splaktar    schedule 16.10.2013


Отговори (2)


непрозрачна стойност, която може да бъде предадена само обратно в кода на Java

Мисля, че това означава, че не можете да предавате Java масив в JavaScript код.

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

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