Retrofit动态设置支持JSON和XML格式转换工厂
2021-09-20 本文已影响0人
冬季穿短裤
日常开发中,网络请求一般数据传输协议格式一般都是固定的,JSON或XML等。但总有一些例外,一个项目中有多种格式,也算是Android开发人员比较头疼的了。
Retrofit-Converter.Factory转换工厂
Retrofit是常用且功能强大的网络请求框架,通过Converter.Factory可以将Bean转为RequestBody,ResponseBody转为Bean。
官方也提供了一些转换工厂,供我们快速开发:retrofit-converters
导入相关依赖
implementation 'com.squareup.retrofit2:retrofit:2.6.2'
implementation 'com.squareup.retrofit2:converter-gson:2.6.2'
implementation 'com.squareup.retrofit2:converter-simplexml:2.6.2'
版本号可替换成最新版本。
提示:SimpleXml已经被官方弃用,官方推荐使用JAXB,当时测试JAXB使用时报错。converter-jaxb
创建ConverterFormat枚举类
/**
* 数据解析的方式
* json或者xml
*/
enum class ConverterFormat {
JSON,
XML
}
声明RequestConverter注解
@Target(
AnnotationTarget.FUNCTION
)
@Retention(AnnotationRetention.RUNTIME)
@MustBeDocumented
annotation class RequestConverter(val format: ConverterFormat = ConverterFormat.JSON)
默认JSON格式。
声明ResponseConverter注解
@Target(
AnnotationTarget.FUNCTION
)
@Retention(AnnotationRetention.RUNTIME)
@MustBeDocumented
annotation class ResponseConverter(val format: ConverterFormat = ConverterFormat.JSON)
默认JSON格式。
自定义JsonOrXmlConverterFactory
class JsonOrXmlConverterFactory private constructor() : Converter.Factory() {
private var jsonFactory: Converter.Factory
private var xmlFactory: Converter.Factory
init {
val gson = GsonBuilder()
.serializeNulls()
.create()
jsonFactory = GsonConverterFactory.create(gson)
xmlFactory = SimpleXmlConverterFactory.createNonStrict()
}
companion object {
fun create() = JsonOrXmlConverterFactory()
}
override fun requestBodyConverter(
type: Type,
parameterAnnotations: Array<Annotation>,
methodAnnotations: Array<Annotation>,
retrofit: Retrofit
): Converter<*, RequestBody>? {
for (annotation in methodAnnotations) {
if (annotation is RequestConverter) {
if (annotation.format == ConverterFormat.JSON) {
return jsonFactory.requestBodyConverter(
type,
parameterAnnotations,
methodAnnotations,
retrofit
)
} else if (annotation.format == ConverterFormat.XML) {
return xmlFactory.requestBodyConverter(
type,
parameterAnnotations,
methodAnnotations,
retrofit
)
}
}
}
return jsonFactory.requestBodyConverter(
type,
parameterAnnotations,
methodAnnotations,
retrofit
)
}
override fun responseBodyConverter(
type: Type,
annotations: Array<Annotation>,
retrofit: Retrofit
): Converter<ResponseBody, *>? {
for (annotation in annotations) {
if (annotation is ResponseConverter) {
if (annotation.format == ConverterFormat.JSON) {
return jsonFactory.responseBodyConverter(type, annotations, retrofit)
} else if (annotation.format == ConverterFormat.XML) {
return xmlFactory.responseBodyConverter(type, annotations, retrofit)
}
}
}
return jsonFactory.responseBodyConverter(type, annotations, retrofit)
}
}
如果没找到相关注解,则使用JSON格式。
使用方法
- 创建Retrofit实例时通过addConverterFactory添加JsonOrXmlConverterFactory
fun init() {
val retrofitBuilder = Retrofit.Builder()
.addConverterFactory(JsonOrXmlConverterFactory.create())
val retrofit = retrofitBuilder.build()
val apiService = retrofit.create(ApiService::class.java)
}
- 在接口上添加注解
@POST
@RequestConverter(ConverterFormat.XML)
@ResponseConverter(ConverterFormat.JSON)
@Headers("Connection: Close")
fun netRelayCtrl(@Url url: String, @Body bean: NetRelayCtrlBean): Observable<NetRelayCtrlResultBean>
不添加RequestConverter、ResponseConverter注解,则默认使用JSON解析。如有错误,还望指正。