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


    @

    日常开发中,网络请求一般数据传输协议格式一般都是固定的,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解析。如有错误,还望指正。

  • 相关阅读:
    独立思考者模型:识别媒体与砖家的谎言 对精确性的痴迷
    独立思考者模型:你相信灵魂转世假说吗? 一次统计的头脑风暴
    独立思考者模型:如何分辨信息的真伪 不要再被虚假信息蒙骗
    独立思考者模型:寻找潜藏在表象背后的真相 探寻真相的方法
    独立思考者模型:避开思维误区的沼泽 我们很多时很蠢
    独立思考者模型:用专家的思维思考问题 从阅读到吸收再到模型建立
    独立思考者模型:如何科学地思考 掌握更正确的思维方式
    eclipse从svn检出项目
    网络通讯框架MINA和XSCOCKET的简单比较
    浏览器的渲染原理简介
  • 原文地址:https://www.cnblogs.com/qq714081644/p/12732779.html
Copyright © 2020-2023  润新知