我正在编写一个整洁的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返回列表
集合,这同样适用于其他对象,如question
、Answery
等。
在Chrome下使用Postman扩展进行测试后,我观察到以下情况(这是一个绊脚石):无论使用哪个REST-api,在响应中都会html" target="_blank">返回通用包装器,但是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;
}
更改了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对象来说,这确实很麻烦和冗长。
是我这样做的方式不对,还是我对改型库的期望值太高了一点?
当一个灯泡时刻熄灭时,这个问题的答案非常简单。
我意识到项目列表可以引用任何对象,这取决于对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()上的错误,如下所示 在一些电话中 然后,在我的主要活动中,我订阅该行为主题并解析错误