retrofit2用simplexml解析xml

来源:互联网 发布:淘宝店铺登录 编辑:程序博客网 时间:2024/06/01 16:38

现在手上的项目后台返回的是XML字符串,用惯了JSON + GSON的我第一考虑的就是自动化解析,那么多接口,那么多属性,用DOM或者萨克斯解析太浪费时间了,而且扩展性也不好。网上的关于retrofit2 + simplexml的的文章真的非常少,可见XML是多么不受客户端欢迎,没办法,胳膊拧不过大腿,只能接受XML传输数据。

//网络compile 'io.reactivex:rxjava:1.1.0'compile 'io.reactivex:rxandroid:1.1.0'compile 'com.squareup.retrofit2:retrofit:2.0.0-beta4'compile 'com.squareup.retrofit2:converter-gson:2.0.0-beta4'compile 'com.squareup.retrofit2:adapter-rxjava:2.0.0-beta4'compile 'com.orhanobut:hawk:2.0.0-Alpha'compile 'com.squareup.okhttp3:logging-interceptor:3.6.0'compile('com.squareup.retrofit2:converter-simplexml:2.0.0-beta4') {    exclude group: 'xpp3', module: 'xpp3'    exclude group: 'stax', module: 'stax-api'    exclude group: 'stax', module: 'stax'}
这是的build.gradle里面的一部分。这个simplexml的的版本一定要跟上面的其他版本一模一样,不然就GG。
初始化retrofit2

public class Api {    private static ApiService SERVICE;    private static XmlApisService xmlApisService;    /**     * 请求超时时间     */    private static final int DEFAULT_TIMEOUT = 8000;    public static XmlApisService getXml(final Context context){        if (xmlApisService == null) {            //手动创建一个OkHttpClient并设置超时时间            OkHttpClient.Builder httpClientBuilder = new OkHttpClient.Builder();            httpClientBuilder.connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS);            httpClientBuilder.addInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY));            /**             *  拦截器             */            httpClientBuilder.addNetworkInterceptor(new Interceptor() {                @Override                public okhttp3.Response intercept(Chain chain) throws IOException {                    Request request = chain.request();                    HttpUrl.Builder authorizedUrlBuilder = request.url()                            .newBuilder()                    //添加统一参数 如手机唯一标识符,token等                            .addQueryParameter("guid", AppTools.getIMEI(context))                            .addQueryParameter("siteid", Constants.GAME_SITE_ID)                            .addQueryParameter("unionid", Constants.GAME_UNIONID)                            .addQueryParameter("version", AppTools.getVersionCode(context)+"")                            .addQueryParameter("plat", Constants.GAME_PLAT);                    Request newRequest = request.newBuilder()                            //对所有请求添加请求头//                            .header("mobileFlag", "adfsaeefe").addHeader("type", "4")                            .method(request.method(), request.body())                            .url(authorizedUrlBuilder.build())                            .build();                    if (chain!=null){                        return  chain.proceed(newRequest);                    }                    return null;                }            });            xmlApisService = new Retrofit.Builder()                    .client(httpClientBuilder.build())                    .addConverterFactory(SimpleXmlConverterFactory.create())                    .addCallAdapterFactory(RxJavaCallAdapterFactory.create())                    .baseUrl(Url.BASE_URL)                    .build().create(XmlApisService.class);        }        return xmlApisService;    }}

辣么多代码,其实关键就是一句addConverterFactory(SimpleXmlConverterFactory.create())这一句。
举个例子服务器返回的XML是这样的
<?xml version="1.0" encoding="utf-8" ?><Results><Result Result="10000" message="" /><Items><Item Src ="http://phonetest.91y.com/common/images/banner01.png"  Remark="" JumpURL="http://m.91y.com/" Type="0"/><Item Src ="http://phonetest.91y.com/common/images/banner02.png"  Remark="" JumpURL="http://m.91y.com/" Type="0"/><Item Src ="http://phonetest.91y.com/common/images/banner02.png"  Remark="" JumpURL="http://m.91y.com/" Type="1"/></Items></Results>
package com.yxsq.fuyun.netbean.home;import com.yxsq.fuyun.netbean.MessageResult;import org.simpleframework.xml.Element;import org.simpleframework.xml.Root;/ ** *由海峰于2017/5/27创建。 * ElementList:申明该元素是一个集合。 *元素:申明该元素只是一个普通属性 * inline = true:ElementList的一个属性,由于ElementList包了一层,如果为false将不能解析。 * required = false:实体类中有,xml中没有,且声明为@Element的,在@Element中加上required = false即可。 * @Root(strict = false):xml中有元素,而实体类中没有,在实体类的@(Root)中加上strict = false如@Root(strict = false)即可。 * http://blog.csdn.net/Picasso_L/article/details/53583507 * http://blog.csdn.net/qqyanjiang/article/details/51199111 * http://blog.csdn.net/qqyanjiang/article/details/51200108 * /@Root(name =“Results”,strict = false)public class HomeBannerResult {    @Element(name =“Result”)    public MessageResult codeMsg;    @Element(name =“Items”)    public HomeListBanner数据;}我相信你们看到我的注解和注释也就明白了,关键是不能用内部类,那是绝对绝对不行的。规规矩矩一个一个类来建。package com.yxsq.fuyun.netbean;import org.simpleframework.xml.Attribute;import org.simpleframework.xml.Root;/ ** *由海峰于2017/5/27创建。 * /@Root(name =“Result”,strict = false)public class MessageResult { @Attribute(name =“Result”,required = false) public String ResultCode; @Attribute(name =“message”,required = false) public String msg;}package com.yxsq.fuyun.netbean.home;import org.simpleframework.xml.ElementList;import org.simpleframework.xml.Root;import java.util.List;/ ** *由haifeng于2017/6/1创建。 * /@Root(name =“Items”,strict = false)public class HomeListBanner {    @ElementList(name =“Item”,inline = true,required = false)    public List <HomeBannerBean> data;}package com.yxsq.fuyun.netbean.home;import org.simpleframework.xml.Attribute;import org.simpleframework.xml.Root;/ ** *由海峰于2017/5/27创建。 * /@Root(name =“Item”,strict = false)public class HomeBannerBean {    @attribute(name= “Src”)    public String src;    @attribute(name= “Remark”)    public String Remark;    @Attribute(name =“JumpURL”)    public String jumpUrl;    @Attribute(name =“Type”)    public String type;}
类已经创建完了,注解也搞完了。比如后台突然加了一个字段,就在HomeBannerBean里面加入一个属性,
调用如下。
//首页banner区展示图片@GET("do.aspx?action=getbannericon")Observable<HomeBannerResult> getHomeBanner(@Query("sign") String sign);

/** * 获取首页轮播图 */public Subscription getHomeBannerData() {    Subscription subscription = Api.getXml(mContext).getHomeBanner(QuaryMD5.getInstants().commendMd5(mContext)).subscribeOn(Schedulers.io())            .observeOn(AndroidSchedulers.mainThread())            .subscribe(new Subscriber<HomeBannerResult>() {                @Override                public void onCompleted() {                }                @Override                public void onError(Throwable e) {                    if (listener!=null){                        listener.onError(Constants.GAME_NET_ERROR);                    }                }                @Override                public void onNext(HomeBannerResult homeBannerResult) {                    if (listener!=null) {                        if ("10000".equals(homeBannerResult.codeMsg.ResultCode)) {                            listener.onBannerRequested(homeBannerResult.data.data);                        } else {                            listener.onError(homeBannerResult.codeMsg.msg);                        }                    }                }            });    return subscription;}
扫描头像,公众号来一波关注呗。



原创粉丝点击