我正在编写一个简洁的Android应用程序以与API交互,这遵循了Google AndroID用户的体验.
该应用程序将使用Retrofit(使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);}
最大的问题是,由于使用了通用包装器,我如何才能使Retrofit返回到List< Site>.无论如何,这可能同样适用于其他对象,例如“问题”,“答案”等.
在Chrome下使用Postman扩展程序进行测试后,我观察到以下内容,这是一个绊脚石,无论使用哪种REST-API,响应中都会返回通用包装器,但是JsON输出中的items字段包含数组在这种情况下的网站数量.
我推断出,在普通包装器中有一个未返回的字段,称为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库设置了过高的期望?
解决方法:
当灯泡瞬间消失时,这个问题的答案非常简单.
我意识到,根据对stackexchange.com网站的API调用,项目列表可以引用任何对象,因此这意味着在对JsON的项目进行反序列化时应使用的一种类.
解决方案非常简单.
CommonSEWrapper.java:
public class CommonSEWrapper<T>{ // snip @Serializedname("items") List<T> mListItems; // snip}
然后,要申请Site对象,站点的REST API的接口将最终变为ISites.java:
public interface ISites{ @GET("/sites") public voID getAllSites(@query("filter") String filtername, Callback<CommonSEWrapper<Site>> cbAllSites);}
最后,通过Retrofit执行REST如下所示:
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! }});
干净,优雅,简单,而且不会与Retrofit的魔法内乱交织.
希望这会帮助其他处于类似困境的人.
请享用.
总结以上是内存溢出为你收集整理的java-带翻新的StackExchange API处理全部内容,希望文章能够帮你解决java-带翻新的StackExchange API处理所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)