前言
Android开发中,我们会经常遇到前端需要解析两种数据格式(json和xml),比如自己服务器返回的是json格式的数据,我们做微信登录的时候,微信返回的格式又是xml格式的。我们可以通过自己编写Retrofit的ConverterFactory来做到可以同时解析两种数据格式。
代码
1.一般我们实例化retrofit实例的时候,都会传入GsonConverterFactory,如果我们需要同时解析两种格式,我们需要重写Converter.Factory()类
2.引入依赖包:
com.squareup.retrofit2:converter-simplexml是retrofit帮我们解析xml的依赖
implementation 'com.squareup.retrofit2:retrofit:2.6.0' implementation 'com.squareup.retrofit2:converter-gson:2.4.0' implementation 'com.squareup.retrofit2:converter-simplexml:2.4.0'
3.重写Converter.Factory()类,在responseBodyConverter方法中,判断到底是那种数据格式然后对应解析。
class JsonOrXmlConverterFactory : Converter.Factory() { private val xmlFactory:Converter.Factory by lazy { SimpleXmlConverterFactory.create() } private val jsonFactory: Converter.Factory by lazy { GsonConverterFactory.create() } companion object { fun create():JsonOrXmlConverterFactory { return JsonOrXmlConverterFactory() } } override fun requestBodyConverter( type: Type, parameterAnnotations: Array, methodAnnotations: Array, retrofit: Retrofit ): Converter? { return super.requestBodyConverter(type, parameterAnnotations, methodAnnotations, retrofit) } override fun responseBodyConverter( type: Type, annotations: Array, retrofit: Retrofit ): Converter? { for(annotation in annotations) { if(annotation !is ResponseFormat) { continue } val value = annotation.value if (ResponseFormat.JSON == value) { return jsonFactory.responseBodyConverter(type, annotations, retrofit) } else if (ResponseFormat.XML == value) { return xmlFactory.responseBodyConverter(type, annotations, retrofit) } } return null }}
4.添加ResponseFormat注解,需要在HttpService中告诉请求到底返回的是xml还是json:
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER)@Retention(AnnotationRetention.RUNTIME)annotation class ResponseFormat(val value: String = "json") { companion object { const val JSON = "json" const val XML = "xml" }}
5.Httpservice注解添加:
(1)当服务端返回格式为json时,ResponseFormat不需要添加参数,默认为json:
@ResponseFormat @FormUrlEncoded @POST("v1/user/getUser2") suspend fun getUser(@Field("openid") openid: String) : ReponseServer
(2)当服务器返回xml时,@ResponseFormat(value = ResponseFormat.XML)添加参数。告诉JsonOrXmlConverterFactory此时需要解析xml。
@ResponseFormat(value = ResponseFormat.XML) @POST("unifiedorder") suspend fun wxPrePay(@Body route:RequestBody) : WXPayReponse @ResponseFormat(value = ResponseFormat.XML) @POST("orderquery") suspend fun wxPayOrderQuery(@Body route: RequestBody) : WXOrderReponse
总结:
到此我们可以通过Retrofit解析json和xml格式,如果大家有疑问或者不足之处,可以在下方评论留言。