日常開發(fā)中,網(wǎng)絡(luò)請求一般數(shù)據(jù)傳輸協(xié)議格式一般都是固定的,JSON或XML等。但總有一些例外,一個項目中有多種格式,也算是Android開發(fā)人員比較頭疼的了。
Retrofit-Converter.Factory轉(zhuǎn)換工廠
Retrofit是常用且功能強大的網(wǎng)絡(luò)請求框架,通過Converter.Factory可以將Bean轉(zhuǎn)為RequestBody,ResponseBody轉(zhuǎn)為Bean。
官方也提供了一些轉(zhuǎn)換工廠,供我們快速開發(fā):retrofit-converters
導入相關(guān)依賴
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已經(jīng)被官方棄用,官方推薦使用JAXB,當時測試JAXB使用時報錯。converter-jaxb
創(chuàng)建ConverterFormat枚舉類
/**
* 數(shù)據(jù)解析的方式
* 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)
}
}
如果沒找到相關(guān)注解,則使用JSON格式。
使用方法
- 創(chuàng)建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解析。如有錯誤,還望指正。