美文网首页安卓开发博客奶牛刀
Retrofit动态设置支持JSON和XML格式转换工厂

Retrofit动态设置支持JSON和XML格式转换工厂

作者: 冬季穿短裤 | 来源:发表于2021-09-20 21:23 被阅读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格式。

    使用方法

    1. 创建Retrofit实例时通过addConverterFactory添加JsonOrXmlConverterFactory
    fun init() {
        val retrofitBuilder = Retrofit.Builder()
            .addConverterFactory(JsonOrXmlConverterFactory.create())
        val retrofit = retrofitBuilder.build()
        val apiService = retrofit.create(ApiService::class.java)
    }
    
    1. 在接口上添加注解
    @POST
    @RequestConverter(ConverterFormat.XML)
    @ResponseConverter(ConverterFormat.JSON)
    @Headers("Connection: Close")
    fun netRelayCtrl(@Url url: String, @Body bean: NetRelayCtrlBean): Observable<NetRelayCtrlResultBean>
    

    不添加RequestConverter、ResponseConverter注解,则默认使用JSON解析。如有错误,还望指正。

    相关文章

      网友评论

        本文标题:Retrofit动态设置支持JSON和XML格式转换工厂

        本文链接:https://www.haomeiwen.com/subject/zbyjgltx.html