关于kotlin serialization集成到retrofit的一些研究

前几天,我一直在找retrofit集成kotlin serialization的资料,才发现,网上的资料是真的少,如果你有幸看到这篇文章,就默默记下来。
关于为什么要急kotlin serialization的问题,相信如果你用gson发现每个属性必须要赋值才能调用到无参构造方法将默认值赋值,这个你使用kotlin 的data class时候,相信对代码追求完美的你会很难受

而使用kotlin serialization,就可以很开心的使用kotlin的特性来使用,另外在闲扯两句kotlin serialization的优势,首先,它是kotlin官方出的一套框架,结合kotlin的使用堪称完美,其次,相信你们也会关注它的解析效率,关于这个,大家都知道程序运行时,使用反射有影响效率,而它使用的是编译插件的方式, 网上的资料也都很多,有兴趣的同学可以自己去测试。

好了,现在直接上干货,在我一开始接触到这个kotlin serialization的时候,我发现每个数据类需要加上@Serializable这个注解,
就比如

@Serializable
data class InfoEntity(val result:T?, val msg:String, val code:String)

@Serializable
data class ResultEntity(val name:String,val phone:String,val age:Int)

关于InfoEntity这个数据类的解析方式:

val json = Json(JsonConfiguration.Stable.copy(unquoted = true))
val result = json.parse(serializerByTypeToken(type),value.string()) as InfoEntity

看到这里,我相信你已经看懂啦,其实type 转换成KSerializer的方法呢,
就是serializerByTypeToken(type)方法,然后就可以愉快的使用json.parse方法解析啦
下面的东西就简单啦,retrofit的转换类ResponseBodyConverter啦

import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonConfiguration
import kotlinx.serialization.serializerByTypeToken
import okhttp3.ResponseBody
import retrofit2.Converter
import java.io.IOException
import java.lang.reflect.Type

class JsonResponseBodyConverter internal constructor(
    private val type: Type
) : Converter {
    private val json = Json(JsonConfiguration.Stable.copy(unquoted = true))

    @Suppress("UNCHECKED_CAST")
    @Throws(IOException::class)
    override fun convert(value: ResponseBody): T = value.use {
        json.parse(serializerByTypeToken(type),value.string()) as T
    }
}

这里呢,也要提一句github上的项目[retrofit2-kotlinx-serialization-converter],如果没有特殊的需求,可以直接引用

implementation 'com.jakewharton.retrofit:retrofit2-kotlinx-serialization-converter:0.4.0'

val contentType = MediaType.get("application/json")
val retrofit = Retrofit.Builder()
    .baseUrl("https://example.com/")
    .addConverterFactory(Json.asConverterFactory(contentType))
    .build()

其实如果打开源码,其实也是使用serializerByTypeToken(type)转换成KSerializer然后用json.parse解析

这里可以自定义将string的类型转换为Date时间类

//{"id":10,"time":"11/01/2001 10:24:14.145"}
@Serializable
data class Result(
    val id: Int,
    @Serializable(with=DateSerializer::class) val time: Date
)

@Serializer(forClass = Date::class)
object DateSerializer: KSerializer {
    private val df: DateFormat = SimpleDateFormat("dd/MM/yyyy HH:mm:ss.SSS")

    override val descriptor: SerialDescriptor =
        StringDescriptor.withName("WithCustomDefault")

    override fun serialize(encoder: Encoder, obj: Date) {
        encoder.encodeString(df.format(obj))
    }

    override fun deserialize(decoder: Decoder): Date {
        return df.parse(decoder.decodeString())
    }
}

今天就讲到这里啦,其他更多自定义介绍可以直接去github的介绍里面看
https://github.com/Kotlin/kotlinx.serialization/blob/master/docs/custom_serializers.md

你可能感兴趣的:(关于kotlin serialization集成到retrofit的一些研究)