如何使用GWT处理JSONP回调?

Cug*_*uga 2 gwt json jsonp

我正在使用GWT,我想发出一个JSONP请求,它在返回时调用我的GWT方法.

但是,我无法弄清楚如何指定在回调时调用的GWT方法.有人可以帮忙吗?这是我的示例代码:

private native void fetchUserData(String accessToken) /*-{
    var callback = "com.company.example.FacebookApi::handleUser";
    var url = "https://graph.facebook.com/me?access_token="+accessToken+"&callback=" + callback;

   // use jsonp to call the graph
   var script = document.createElement('script');
    script.src = url;
    document.body.appendChild(script);

  }-*/;

  public void handleUser(Object o) {
    Window.alert("Received object with class: " + o.getClass().getName())
  }
Run Code Online (Sandbox Code Playgroud)

此代码从此示例移植:Facebook没有SDK.

或者,我刚刚发现有一个GWT JsonpRequestBuilder,我还没有机会使用它,但如果有人可以在不使用任何本机代码的情况下给出一个例子......那就更好了.

谢谢!

Cug*_*uga 6

弄清楚了,在很大程度上要归功于这些例子:

Gwt + JSONP

与Gwt,Jsonp的跨域请求

GWT中的跨站点引用

这是更新的代码,根据注释(没有指定回调,使用Javascript覆盖类型)

  private void fetchDataUsingGwt() {
    String url = "https://graph.facebook.com/me?access_token=" + accessToken;
    JsonpRequestBuilder requestBuilder = new JsonpRequestBuilder();
    requestBuilder.requestObject(url, new AsyncCallback<FbUser>() {
  @Override
  public void onFailure(Throwable caught) {
    Window.alert(caught.getMessage());
  }

  @Override
  public void onSuccess(FbUser fbUser) {
      if (fbUser.isError()) {
        StringBuilder builder = new StringBuilder();
        builder.append("Fb error: ");
        builder.append(fbUser.getError().getMessage() + ", ");
        builder.append(fbUser.getError().getCode());
        String message = builder.toString();
        Window.alert(message);
        return;
      }

      StringBuilder builder = new StringBuilder();
      builder.append("Fetched user: " + fbUser.getFirstName() + " " + fbUser.getLastName());
      builder.append(" from " + fbUser.getHometown().getName());
      builder.append(" born on " + fbUser.getBirthday());
      builder.append(" with id " + fbUser.getId() + " and email " + fbUser.getEmail());
      builder.toString();
      String details = builder.toString();
      Window.alert("Got: " + details);
  }
});
Run Code Online (Sandbox Code Playgroud)

}

并且使用JSO自动包装响应,如下所示:

  public class FbError extends JavaScriptObject {
    protected FbError() {
    }

    public final native String getMessage() /*-{
            return this.message;
    }-*/;

    public final native String getType() /*-{
            return this.type;
    }-*/;

    public final native String getCode() /*-{
            return this.code;
    }-*/;

    public final native String getSubCode() /*-{
            return this.error_subcode;
    }-*/;

  }

  public class Hometown extends JavaScriptObject {
    protected Hometown() {
    }

    public final native String getName() /*-{
            return this.name;
    }-*/;

    public final native String getId() /*-{
            return this.id;
    }-*/;
  }

  public class ErrorableJso extends JavaScriptObject {

    public boolean isError() {
      return getError() != null;
    }

    public final native FbError getError() /*-{
            return this.error;
    }-*/;
  }

  public class FbUser extends ErrorableJso {

    // TODO: Separate call needed to retrieve profile pic

    protected FbUser() {
    }

    public final native String getFirstName() /*-{
            return this.first_name;
    }-*/;

    public final native String getLastName() /*-{
            return this.last_name;
    }-*/;

    public final native String getId() /*-{
            return this.id;
    }-*/;

    public final native String getBirthday() /*-{
            return this.birthday;
    }-*/;

    public final native String getEmail() /*-{
            return this.email;
    }-*/;

    public final native Hometown getHometown() /*-{
            return this.hometown;
    }-*/;
  }
Run Code Online (Sandbox Code Playgroud)

为了完整性,这是JSO包装的原始JSON响应.由于继承,FbUser如果出现如下错误,则使用相同的对象:

{
   "error": {
      "message": "Error validating access token: Session has expired at unix time 1342044000. The current unix time is 1342050026.",
      "type": "OAuthException",
      "code": 190,
      "error_subcode": 463
   }
}
Run Code Online (Sandbox Code Playgroud)

或者预期的User对象:

{
   "id": "23232323",
   "name": "Andrew Cuga",
   "first_name": "Andrew",
   "last_name": "Cuga",
   "link": "http://www.facebook.com/TheAndy",
   "username": "TheAndy",
   "birthday": "02/20/2011",
   "hometown": {
      "id": "108530542504412",
      "name": "Newark, Delaware"
   } // ... etc
}
Run Code Online (Sandbox Code Playgroud)

请注意,JSON响应中的errorhometown字段很容易包装到JavaScriptObjects中.

  • 您可能还会考虑使其更通用,并且无需进行任何手动转换即可返回任何[Javascript覆盖类型](https://developers.google.com/web-toolkit/doc/latest/DevGuideCodingBasicsOverlay).这样,当您开始使用更多API方法时,您最终不会得到太多的代码重复. (3认同)
  • requestBuilder.setCallbackParam( "回调"); 是不必要的,这是默认值.我也同意Chris的观点,叠加类型将使您的生活更轻松,代码更清晰. (2认同)