使用改造的stackexchange API处理



我正在编写与API交互的整洁应用程序,该应用程序遵循Google Android用户体验。

应用程序将使用改造(使REST-API机制更加容易)。

现在,我创建了与每个API调用对应的Java类。

例如,以这种方式处理/sites API的Site.java类:

这是简洁的:

public class Site{
    @SerializedName("api_site_parameter") String mApiSiteParameter = "";
    // snip
}

以这种方式连接接口,称为ISites.java

public interface ISites{
    @GET("/sites")
    public void getAllSites(@Query("filter") String filterName, 
                            Callback<List<Site>> cbAllSites);
}

最大的问题是,由于使用了通用包装器,因此如何使改造返回List<Site>集合,无论如何,这都可以同样适用于其他对象,例如QuestionAnswer等。

在Chrome下使用Postman扩展测试后,我观察到以下是一个绊脚石,在响应中返回了公共包装器,无论使用哪种REST-API,无论使用哪种REST-API,但是,JSON输出中的items字段,在这种情况下包含Site的数组。

我推论出来的是,普通包装器中有一个未返回的字段,称为 type ,这里的想法是在... 上作弊,因为它不是其中的一部分过滤器,这意味着必须通过/filter/create API创建一个新的过滤器,并将其作为调用的一部分应用于改造的RestAdapter调用,如:

RestAdapter ra = new RestAdapter.Builder()
   .setServer("http://api.stackexchange.com/2.1")
   .setLogLevel(LogLevel.FULL)
   .build();
ISites sites = ra.create(ISites.class);
sites.getAllSites("my_commonwrapper_filter", Callback<Site>(){
   @Override
   public void failure(RetrofitError argRetrofitError){
   }
   @Override
   public void success(List<Site> sites, Response response){
   }
});

研究了GSON的自定义TypeAdapterFactory之后,在这里回答了,我在这里错过了一些东西,这就是我到目前为止的。

创建了一个称为SEWrapper.java的类,该类是这样的:

public class SEWrapper{
    @SerializedName("items") List<Class ?> mListItems;
    @SerializedName("type") String mJsonObjType;
}

在网站周围更改。Java源使用SEWrapper而不是Site,然后修改了其余的调用。

此代码是根据stackoverflow上的问题改编的

private class SEWrapperTypeAdapterFactory extends CustomizedTypeAdapterFactory<SEWrapper> {
    private SEWrapperTypeAdapterFactory() { super(SEWrapper.class); }
    @Override
    protected void beforeWrite(SEWrapper source, JsonElement toSerialize) {
       // Ignored for now as all this is Read Only operation!
    }
    @Override
    protected void afterRead(JsonElement deserialized) {
       String typeOfJsonObj = deserialized.getAsJsonObject().get("type").getAsString();
       if (typeOfJsonObj.equalsIgnoreCase("site")){
          JsonArray jSiteArray = deserialized.getAsJsonObject().get("items").getAsJsonArray();
          // Convert that to List<Site> type which I cannot figure out
       }
   }

Am是关于如何解决这个绊脚石的想法。

我可以将其重写以返回改装的Response对象,并手动解析每个JSON对象,并创建该类型Site的列表,它确实会为返回的每个API对象感到笨拙且漫长。

我是以错误的方式这样做,还是在改造库中设置了我的期望?

当灯泡瞬间熄灭时,这个问题的答案非常简单。

我意识到项目列表可以参考任何对象,具体取决于 stackexchange.com 网站的API调用,因此,这意味着类型的类型类应应当JSON的items被估算时使用。

解决方案很简单。

commsewrapper.java

public class CommonSEWrapper<T>{
   // snip
   @SerializedName("items") List<T> mListItems;
   // snip
}

然后申请Site对象,该网站REST API的接口最终会像这样, isites.java.java

public interface ISites{
   @GET("/sites")
    public void getAllSites(@Query("filter") String filterName, 
                            Callback<CommonSEWrapper<Site>> cbAllSites);
}

最后,通过改造的其余执行方式看起来像这样:

RestAdapter ra = new RestAdapter.Builder()
        .setServer("http://api.stackexchange.com/2.1")
        .build();
ISites sites = ra.create(ISites.class);
ra.getAllSites("", new Callback<CommonSEWrapper<Site>>(){
   @Override
   public void failure(RetrofitError argRetrofitError){
   }
   @Override
   public void success(CommonSEWrapper<Site> sites, Response response){
       // sites is filled in, just like magic!
   }
});

干净,优雅和简单,没有弄乱改造的魔术的内部。

希望这将帮助其他发现自己经历过类似困境的人。

享受。

最新更新