2012-07-11 69 views
2

我正在使用GWT,我想创建一个JSONP请求,它在返回时调用我的GWT方法。如何使用GWT处理JSONP回调?

但是,我无法弄清楚如何指定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()) 
    } 

此代码是从这个例子移植:Facebook Without SDK

另外,我刚刚发现有一个GWT JsonpRequestBuilder,我还没有机会使用,但如果任何人都可以举一个例子,而不使用任何本机代码......那就更好了。

谢谢!

回答

6

想通了,由于在很大程度上这些例子:

Gwt + JSONP

Cross Domain Requests with Gwt, Jsonp

Cross site referenceing in GWT

下面是更新后的代码,每个注释(没有指定的回调,使用Javascript Overlay Type)

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

}

,并且响应使用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; 
    }-*/; 
    } 

为了完整性,这是原始JSON响应JSO包装。因继承,使用相同的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 
    } 
} 

或者预期的用户对象:

{ 
    "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 
} 

注意errorhometown领域的JSON响应是轻松包装成JavaScriptObjects。

+3

您可能还会考虑使其更通用,并且无需任何手动转换即可返回任何[Javascript Overlay Type](https://developers.google.com/web-toolkit/doc/latest/DevGuideCodingBasicsOverlay)。这样,当你开始使用更多的API方法时,不会导致代码重复太多。 – 2012-07-11 22:39:24

+2

requestBuilder.setCallbackParam(“callback”); 是不必要的,这是默认设置。我也同意Chris的观点,覆盖类型会让你的生活更轻松,代码更干净。 – LINEMAN78 2012-07-11 22:44:20

+0

感谢你们俩。我很快就知道这个回调并不是必需的,然后把它拿出来。我现在正忙着重叠 - 谢谢! – Cuga 2012-07-11 23:36:21