可以从GWT中的Javascript访问Java对象吗?

时间:2013-12-20 18:13:41

标签: java javascript gwt rpc

我的目标是直接从javascript启动RPC调用。我想出了伪造回调的方法(因为RPC的异步性质),但我无法弄清楚如何将自定义对象变成javascript。

所以,我创建了一个名为Interop的类,我静态地创建了我感兴趣的服务(必须使用静态,因为我可以使用它,我认为它现在不相关):< / p>

public class Interop {
    private static final GreetingServiceAsync service = GWT.create(GreetingService.class);
    ...
}

然后我创建一个将执行异步调用并处理响应的函数:

public static void greetServer(final String success, final String failure) {
    service.greetServer(
        "Homer", 
        new AsyncCallback<String>() {
            public void onFailure(Throwable caught) {
                callback(failure, caught.toString());

            }
            public void onSuccess(String result) {
                callback(success, result);
            }
        }
    );
}

然后我创建一个JSNI函数将此函数导出到javascript,我从onModuleLoad()调用:

public static native void export() /*-{
    $wnd.greetServer = $entry(@package.Interop::greetServer(Ljava/lang/String;Ljava/lang/String;));
}-*/;

还创建另一个JSNI函数来处理回调:

public static native void callback(String func, String response) /*-{
    $wnd[func](response);
}-*/;

因此,我最初为成功和失败传递给greetServer()的函数名称被JSNI称为回调函数。当处理字符串或(我假设)一个原始类型时,这一切都很有效。但是,当我尝试使用自定义类型(请注意更改的自定义类型参数)时:

public static native void callback(String func, Custom response) /*-{
    $wnd[func](response);
}-*/;

然后在javascript中结束的东西不起作用。它似乎是一个带有级联数组的javascript对象,并且没有任何方法可用。

所以,问题是,如何从javascript(而不是JSNI)中访问非基本或原语的Java源对象?从我可以告诉JavaScriptObject需要源于javascript,但在我的情况下,我的对象源自Java。我该怎么办?

我还研究了gwt-exporter,它展示了如何从javascript实例化java东西,但不知道如何在javascript中访问java源代码。

我知道这有点令人困惑所以如果您有任何疑问,请告诉我。谢谢!

1 个答案:

答案 0 :(得分:0)

使用gwt-exporter,这可能是您的代码:

// Create and export a closure used to wrap javascript callbacks
@ExportClosure
public static interface InteropCallback extends Exportable {
  void exec(String message);
}

// Make your Interop class exportable and export methods in it
@ExportPackage("foo")
@Export
public static class Interop implements Exportable {
  final static GreetingServiceAsync service = GWT.create(GreetingService.class);

  public static void greeting(String message, 
                              final InteropCallback success,
                              final InteropCallback error) {
    service.greetServer(message, new AsyncCallback<String>() {
      public void onFailure(Throwable caught) {
        error.exec(caught.getMessage());
      }
      public void onSuccess(String result) {
        success.exec(result);
      }
    });
  }
}

// In your onModuleLoad you have to make gwt-exporter export your stuff
@Override public void onModuleLoad() {
  ExporterUtil.exportAll();
  ...
}

最后从手写的javascript中调用你的java方法

window.foo.Interop.greeting("Hello", 
                            function(s){console.log(s)},
                            function(s){console.log(s)}
                            );