【问题标题】:Can Java objects be accessed from Javascript in GWT?可以从 GWT 中的 Javascript 访问 Java 对象吗?
【发布时间】:2014-01-09 16:03:44
【问题描述】:

我的目标是直接从 javascript 发起 RPC 调用。我想出了伪造回调的方法(因为 RPC 的异步性质),但我不知道如何将自定义对象放入 javascript。

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

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 函数来将此函数导出到我从 onModuleLoad() 调用的 javascript:

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 的东西。

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

【问题讨论】:

    标签: java javascript gwt rpc


    【解决方案1】:

    使用 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)}
                                );
    

    【讨论】:

    • 抱歉,回复需要一段时间,但感谢您的意见!您的示例当然似乎对我有用,并且将是一个很好的起点。我想我误解了一些东西,甚至可能不需要使用 gwt-exporter,但如果我需要它,我很高兴知道它在那里。谢谢!
    猜你喜欢
    • 2012-05-10
    • 1970-01-01
    • 2013-09-20
    • 2020-12-03
    • 2012-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-10
    相关资源
    最近更新 更多