@
目錄
日常開發中,網絡請求一般數據傳輸協議格式一般都是固定的,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解析。如有錯誤,還望指正。