一般情况下,我们在使用retrofit的时候,只会处理到json的解析,加入GsonConverterFactory即可,但是有时候后台突然就卖个萌,给你返回个xml的,那你就懵逼了,下面讲解下retrofit+json+xml的解析。
retrofit原则上是支持多重添加转化器的,形式如下:
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(Constant.API_BASE_TRANS)
.client(client)
.addConverterFactory(gsonConverterFactory)
.addConverterFactory(simpleXmlConverterFactory) .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
但是事与愿违,经过测试,发现会出现点问题,将两者位置交换后,问题又消失了,但是考虑其稳定性,我们最好还是分开添加。
dagger大法
- 依赖
严格按照此格式,否则可能导致失败!
compile ('com.squareup.retrofit2:converter-simplexml:2.0.1'){
exclude group: 'xpp3', module: 'xpp3'
exclude group: 'stax', module: 'stax-api'
exclude group: 'stax', module: 'stax'
}
- 首先将xml请求的api接口单独分开,如NewsApi,实现如下
public interface NewsApi {
/*新闻资讯首页*/
@GET("InfoService/InfoService.ashx")
Observable<NewsDataXml> getNewsData(@Query("FunctionId") String id, @Query("WhereValue") String datePre, @Query("PageIndex") String currentPage, @Query("PageSize") String pageSize);
}
正常的json返回api如下
public interface ClientApi {
@GET("PrefectureTree")
Observable<List<TransBase>> getTransData(@Query("instID") String instID);
……
}
- Module
下面列出核心部分,返回两个接口类,次要部分(参数引用略)
@Provides
@Singleton
public ClientApi provideClientApi(OkHttpClient client, GsonConverterFactory gsonConverterFactory) {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(Constant.API_SHARE)
.client(client)
.addConverterFactory(gsonConverterFactory)
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
return retrofit.create(ClientApi.class);
}
@Provides
@Singleton
public NewsApi provideNewsApi(OkHttpClient client, SimpleXmlConverterFactory simpleXmlConverterFactory) {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(Constant.API_URL3)
.client(client)
.addConverterFactory(simpleXmlConverterFactory)
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
return retrofit.create(NewsApi.class);
}
- Component
牢记加入新接口NewsApi的返回,提供引用(否则编译不通过)
@Singleton
@Component(modules = {AppModule.class, ClientApiModule.class})
public interface AppComponent {
Context context();
ClientApi clientApi();
NewsApi newsApi();
void inject(App application);
}
最后正常初始化component即可,dagger部分完成,下面介绍xml的序列化部分,怎么讲xml转为javabean。
- 无脑贴上待解析xml数据
<?xml version="1.0" encoding="utf-8"?>
<data>
<info id="2016042011100050" cName="信息点评(网站)" tName="" code="" f=""> <![CDATA[ 大盘继续缩量 短期将迎变盘 ]]> </info>
<info id="2016042011100231" cName="新股新闻" tName="" code="" f=""> <![CDATA[ 22日申购预告 ]]> </info>
<info id="2016042011100232" cName="新股新闻" tName="" code="" f=""> <![CDATA[ 21日申购通知 ]]> </info>
<info id="2016042011100230" cName="新股新闻" tName="" code="" f=""> <![CDATA[ 20日中签通知 ]]> </info>
......
</data>
- javabean
NewsDataXml.class
@Root(name = "data",strict = false)
public class NewsDataXml {
@ElementList(required = true,inline = true,entry = "info")
public List<NewsXml> list;
public List<NewsXml> getList() {
return list;
}
public void setList(List<NewsXml> list) {
this.list = list;
}
}
NewsXml.class
@Root(name = "info",strict = false)
public class NewsXml {
@Attribute
public String id;
@Attribute
public String cName;
@Text
public String info;
public String getcName() {
return cName;
}
public void setcName(String cName) {
this.cName = cName;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getInfo() {
return info;
}
public void setInfo(String info) {
this.info = info;
}
}
对于以上不懂的,可以戳,可以自己搜索。
好了,大功告成,只差最后一步调用了,调用方式和json一样,只不过api的类不一样了。