【发布时间】:2014-02-11 12:18:20
【问题描述】:
我正在编写一个简洁的 Android 应用程序来与 API 交互,它遵循 Google Android 用户体验。
应用程序将使用 Retrofit(使 REST-api 机制更容易)。
现在,我已经创建了对应于每个 API 调用的 Java 类。
例如,Site.java 类以这种方式处理 /sites API:
为了简洁起见,这是浓缩的:
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);
}
最大的问题是,由于使用了通用包装器,我怎样才能让 Retrofit 返回一个 List<Site> 集合,这同样适用于其他对象,例如 Question、Answer 等等。
在 Chrome 下使用 Postman 扩展进行测试后,我观察到以下情况,这是一个绊脚石,无论使用哪个 REST-api,都会在响应中返回公共包装器,但是 JSON 中的 items 字段输出,在这种情况下包含Site 的数组。
我推断,通用包装器中有一个字段没有返回,称为type 这里的想法是稍后作弊......而且,因为它不是一部分过滤器,这意味着必须通过 /filter/create API 创建一个新过滤器,并将其作为调用的一部分应用于 Retrofit 的 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 即 answered here on SO 之后,我是否在这里遗漏了什么,这是我目前所拥有的。
创建了一个名为 SEWrapper.java 的类,如下所示:
public class SEWrapper{
@SerializedName("items") List<Class ?> mListItems;
@SerializedName("type") String mJsonObjType;
}
围绕 Site.java 源更改为使用 SEWrapper 而不是 Site,并修改了 REST 调用。
这段代码改编自 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
}
}
我不知道如何绕过这个绊脚石。
理论上,我可以重写它以返回 Retrofit 的 Response 对象并手动解析每个 JSON 对象以及创建该类型的列表 Site,对于每个 API 来说确实感觉很麻烦且冗长返回的对象。
我这样做是错误的方式,还是我对 Retrofit 库的期望过高?
【问题讨论】:
标签: java android json api retrofit