gson 如何用Reified,Generics,Interface和Kotlin解码json数据?

l7mqbcuq  于 2022-11-06  发布在  Kotlin
关注(0)|答案(1)|浏览(184)

如何用Reified,Generics,Interface和Kotlin解码json数据?
我创建了一个项目,我把代码和指令运行:https://github.com/paulocoutinhox/kotlin-gson-sample
但基本上代码是:

import com.google.gson.Gson
import com.google.gson.reflect.TypeToken

interface Serializer {
    fun <T> decodeValue(data: String): T?
}

class JsonSerializer : Serializer {
    override fun <T> decodeValue(data: String): T? {
        try {
            val type = object : TypeToken<T>() {}.type
            val gson = Gson()
            return gson.fromJson<T>(data, type)
        } catch (e: Exception) {
            println("Error when parse: ${e.message}")
        }

        return null
    }
}

class Request<T>(val r: T)

inline fun <reified T> callSerializer(json: String): T? {
    val serializer = JsonSerializer()
    val decoded = serializer.decodeValue<Request<T>>(json)
    return decoded?.r
}

fun main() {
    val finalValue = callSerializer<Request<String>>("{\"r\": \"test\"}")
    println("Decoded data is: $finalValue")
}
  • Request类有一个名为r的泛型类型的内部值。
  • 我正在尝试将上面的json数据转换为Request类,并将r从json绑定到字符串类型。

但我得到的错误:

> Task :run FAILED
Exception in thread "main" java.lang.ClassCastException: class com.google.gson.internal.LinkedTreeMap cannot be cast to class Request (com.google.gson.internal.LinkedTreeMap and Request are in unnamed module of loader 'app')
        at MainKt.main(Main.kt:36)
        at MainKt.main(Main.kt)

gson库认为它是一个LinkedTreeMap,而不是Request类。
这怎么解决呢?

  • 谢谢-谢谢
jslywgbw

jslywgbw1#

import com.google.gson.Gson
import com.google.gson.reflect.TypeToken

interface Serializer {
    fun <T> decodeValue(data: String): Request<T>?
}

class JsonSerializer : Serializer {
    override fun <T> decodeValue(data: String): Request<T>? {
        try {
            val type = object : TypeToken<Request<T>>() {}.type
            val gson = Gson()
            return gson.fromJson<Request<T>>(data, type)
        } catch (e: Exception) {
            println("Error when parse: ${e.message}")
        }

        return null
    }
}

class Request<T>(val r: T)

inline fun <reified T> callSerializer(json: String): T? {
    val serializer = JsonSerializer()
    val decoded = serializer.decodeValue<T>(json)
    return decoded?.r
}

fun main() {
    println("Decoded data is: ${callSerializer<String>("{\"r\": \"test\"}")}")
}

相关问题