简体   繁体   English

是否可以将 kotlinx-datetime 与 Gson 一起使用

[英]Is it possible to use kotlinx-datetime with Gson

I have JSON data which is retrieved from the local realm database.我有从本地 realm 数据库中检索到的 JSON 数据。 I'm trying to convert it into the corresponding data class. I have an ISO date field我正在尝试将其转换为相应的数据 class。我有一个 ISO 日期字段

{
  ....
  "createdAt" : "2022-05-04T10:16:56.489Z"
  ....

}

What I'm trying to do is to convert this string date field into kotlinx-datetime 's Instant object which is a serializable class. Thus I made my data class as我要做的是将此字符串日期字段转换为kotlinx-datetimeInstant object,这是一个可序列化的 class。因此我将数据 class 设为

import kotlinx.datetime.Instant

data class PollPinComment(
    ...
    val createdAt: Instant? = null,
    ...
)

Which doesn't work and gives an error as follows哪个不起作用并给出如下错误

com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 288 path $[0].createdAt

I'm sure that I might need to write some serialization/deserialization logic with gson to convert this string into Instant object. So my question is how can I do that?我确定我可能需要使用 gson 编写一些序列化/反序列化逻辑,以将此字符串转换为Instant object。所以我的问题是我该怎么做? Thanks in advance提前致谢

GSON parses only basic data types, such as Int, String, double... Other classes that need to be parsed must also consist of these basic data types. GSON只解析基本数据类型,比如Int、String、double... 其他需要解析的类也必须由这些基本数据类型组成。 could do like this:可以这样做:

 data class PollPinComment(val createdAt: String ){

 fun  getCreatedAt(): Instant{
     return  Instant.parse(createdAt) 
 }
 }

You can create a custom Deserializer for this and register it as type adapter to your Gson object.您可以为此创建一个自定义Deserializer ,并将其注册为您的Gson object 的type adapter

class InstantDateDeserializer: JsonDeserializer<Instant> {
    override fun deserialize(
        json: JsonElement?, 
        typeOfT: Type?, 
        context: JsonDeserializationContext?
    ): Instant? {
        return json?.asString?.let {
            Instant.parse(it)
        }
    }
}

Create Gson() object pasing that deserializer as type adapter创建Gson() object 将该deserializer作为type adapter

val gson: Gson = GsonBuilder ()
    .registerTypeAdapter(Instant::class.java, DateDeserializer())
    .create()

If you are using it with Retrofit如果您将它与Retrofit一起使用

In Retrofit builder pass this to GsonConverterFactoryRetrofit构建器中将其传递给GsonConverterFactory

val retrofit = Retrofit.Builder()
    .baseUrl(BASE_URL)
    .addConverterFactory(GsonConverterFactory.create(gson))
    .build()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM