当前位置: 首页 > 知识库问答 >
问题:

用改型处理StackExchange API

颜思淼
2023-03-14

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

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

最大的问题是,由于使用了公共包装器,如何使referfit返回列表 集合,这同样适用于其他对象,如questionAnswery等。

在Chrome下使用Postman扩展进行测试后,我观察到以下情况(这是一个绊脚石):无论使用哪个REST-api,在响应中都会html" target="_blank">返回通用包装器,但是JSON输出中的items字段在本例中包含site数组。

我推断出,在通用包装器中有一个字段没有返回,叫做type,这里的想法是以后再作弊...而且,由于它不是筛选器的一部分,这意味着必须通过/filter/createAPI创建一个新的筛选器,并将其作为调用的一部分应用于改型的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;
}

更改了site.java源代码,使用sewrapper而不是site,并修改了REST调用。

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

理论上,我可以重写它以返回改型的response对象,并手动解析每个JSON对象,同时创建该类型的列表site,对于返回的每个API对象来说,这确实很麻烦和冗长。

是我这样做的方式不对,还是我对改型库的期望值太高了一点?

共有1个答案

汝弘深
2023-03-14

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

我意识到项目列表可以引用任何对象,这取决于对StackExchange.com站点的API调用,因此这意味着当JSON的items被反序列化时将使用一种类型的类。

解决办法相当简单。

public class CommonSEWrapper<T>{
   // snip
   @SerializedName("items") List<T> mListItems;
   // snip
}
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!
   }
});

希望这能帮助那些发现自己处于类似困境的人。

享受吧。

 类似资料:
  • 我的服务器为所有请求返回一个基本的JSON结构,如下所示: 其中可以是true或false,数据可以返回许多内容,从到应用程序可能需要的数据。 需要更改/添加到我的改型API调用中的内容是什么?

  • 但是,使用retrofit每个请求都有其错误处理回调: 我如何在一个地方处理所有错误?

  • 使用焊接1.1.13。最终在测试与Arquillian...... 假设我向一个字段注入了一些不稳定的东西。比如一个受更改影响的属性,我希望拥有注入点的bean接收更改事件。考虑创建一个CDI扩展。 捕获ProcessAnnotatedType事件并查找在字段注入点上具有自定义注释的所有字段: 之后,他甚至抓取了字段的所有注入点,并用对应于“包装器”类型的新字段替换了底层的WeldField。否则

  • POJO: 在上面的代码POJO TrackerRefResponse.java前缀responseMessage被设置为responseMessage类型的string或object,所以我们可以用同名的ref变量(java basics:)创建POJO,所以我正在为Referfit中的dynamic寻找相同的解决方案。我知道这在带有异步任务的普通http客户端中非常容易,但这不是REST-AP

  • 以下是GSON的例外: 改型实例是使用GsonConverterFactory创建的

  • 现在,我使用subject来捕获。subscribe()上的错误,如下所示 在一些电话中 然后,在我的主要活动中,我订阅该行为主题并解析错误