retrofit2用simplexml解析xml

现在手上的项目后台返回的是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;
}
扫描头像,公众号来一波关注呗。



  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值