Как преобразовать возвращаемое значение из javascript в java в GWT JSNI?

Метод JSNI не принимает никаких параметров, но возвращает тип объекта Java:

 public static native String nativeJSFuncGwt() /*-{
        $wnd.console.log($wnd.someJSFunc());
        return "" + $wnd.someJSFunc() + "" ;
    }-*/;


//someJSFunc returns { abc:xcv, def:asd}

Я вижу, что значение печатается в консоли javascript, но сторона java не может понять приведение.

Это потому, что собственный метод не принимает никаких параметров?

String tokenFromNativeJS = nativeJSFuncGwt(); // String value is null 

Документация также недостаточно ясна в GWT.


person Raghvendra Kumar    schedule 09.09.2019    source источник


Ответы (2)


Шаг первый, избегайте JSNI, вам лучше определить метод JsInterop, который обеспечивает тот же доступ к API. JSNI по-прежнему будет работать в GWT2, но JsInterop — это путь вперед для GWT3, и часто его намного легче читать и писать. Это будет выглядеть примерно так:

@JsMethod(name = "someJSFunc", namespace = JsPackage.GLOBAL)
public static native String someJSFunc();

Шаг второй: определите тип Java, который соответствует ожидаемому возвращаемому значению JS. Это будет работать либо с JSNI, либо с JsInterop. В JSNI вы должны создать подкласс JavaScriptObject и предоставить методы для доступа к полям (см. http://www.gwtproject.org/doc/latest/DevGuideCodingBasicsJSNI.html и другие документы для получения более подробной информации, но, как и в первом шаге, я не буду вдаваться в подробности здесь). Для вашего примера объекта это будет выглядеть так в JsInterop:

@JsType(isNative = true, name = "Object", namespace = JsPackage.GLOBAL)
public class SomeReturnObject {
    public String abc;
    public double def;
}

Очевидно, замените имена полей и типы тем, что подходит для вашего собственного проекта. Дайте этому новому типу имя-заполнитель, вот как будет выглядеть ваш глобальный someJsFunc:

@JsMethod(name = "someJSFunc", namespace = JsPackage.GLOBAL)
public static native SomeReturnObject someJSFunc();

И вы будете использовать его, как вы ожидаете, в простой Java - больше не нужно писать JSNI:

SomeReturnObject object = someJSFunc();
DomGlobal.console.log(object.abc + ": " + object.def);
person Colin Alworth    schedule 09.09.2019
comment
У нас есть устаревшая кодовая база, которая использует gwt 2.4.0 и не может быть обновлена ​​до более новой версии. - person Raghvendra Kumar; 10.09.2019
comment
Если вам не нужна поддержка какого-либо браузера, выпущенного за последние 8 лет, это должно отлично работать. В этом случае вам нужно будет создать подкласс JavaScriptObject и добавить соответствующие методы получения для чтения из этих свойств abc/def. Для такого устаревшего кода рассмотрите в качестве примера stackoverflow.com/a/15497221/860630, но в 2019 году это не правильный ответ на новый вопрос. - person Colin Alworth; 10.09.2019
comment
На самом деле это первое место, где я вижу хорошее, простое и понятное объяснение того, как чего-то добиться с помощью Jsinterop. Я всегда читаю об использовании Jsinterop, но не могу найти никакой документации по этому поводу. Я не думаю, что это даже упоминается на gwtproject.org - person Knarf; 18.09.2019
comment
@Knarf, хотя я связал страницу JSNI, есть также страница JsInterop, на которой обсуждаются некоторые из этих вещей с краткими примерами: gwtproject.org/doc/latest/DevGuideCodingBasicsJsInterop.html. Основная сила, которую я вижу в вопросах и ответах, подобных этому, заключается в том, что мы начинаем с конкретной проблемы и устраняем ее, вместо того, чтобы описывать в целом, что может сделать весь набор инструментов — чем больше хороших вопросов приведет к более полезным ответам! - person Colin Alworth; 18.09.2019

Я публикую здесь то, что наконец сработало из-за ограничения версии GWT (2.4)

Из документа GWT:

Исходящий тип Java:

Любой другой объект Java (включая массивы)

Что необходимо пройти:

Java-объект правильного типа, который должен быть создан в коде Java; Объекты Java не могут быть созданы «из воздуха» в JavaScript

Мой код с модификацией хотел бы:

public static native MyObject nativeJSFuncGwt(MyObject obj) /*-{

   var xyz = $wnd.someJsFunc();

   [email protected]::setter1(Ljava/lang/String;)(xyz);

   return obj;

 }-*/;

Я бы хотел, чтобы документация была более понятной.

person Raghvendra Kumar    schedule 18.09.2019