我正在编写一个简洁的 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,都会在响应中返回公共包装器,但是items
JSON 输出中的字段包含数组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){
}
});
在研究了在 SO 上回答TypeAdapterFactory
的Gson 的习俗之后,我是否在这里遗漏了一些东西,这就是我到目前为止所拥有的。
创建了一个名为的类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 对象,同时创建一个该类型的 List ,Site
对于返回的每个 API 对象,它确实感觉很麻烦且冗长。
我这样做是错误的方式还是我对 Retrofit 库的期望有点太高了?