Klaxon 解析空枚举

Posted

技术标签:

【中文标题】Klaxon 解析空枚举【英文标题】:Klaxon parse null enum 【发布时间】:2020-04-25 05:48:58 【问题描述】:

我正在尝试使用 Klaxon 库和 kotlin 解析包含枚举的 json 响应。下面是一个测试。如果我有一个可为空的枚举,我的解析将失败。有没有办法正确地做到这一点? Klaxon 库有问题吗?

import com.beust.klaxon.Klaxon
import org.junit.jupiter.api.Test
import kotlin.test.assertEquals
import kotlin.test.assertNotNull
import kotlin.test.assertNull

enum class MyEnum  FIRST, SECOND, THIRD 

class WithEnum 
    var myVal: MyEnum? = null


class EnumTest 
    @Test
    fun `should deserialize null enum`() 
        val parsed = Klaxon().parse<WithEnum>(" \"myVal\":null")
        assertNotNull(parsed)
        assertNull(parsed.myVal)
    

    @Test
    fun `should deserialize proper enum`() 
        val parsed = Klaxon().parse<WithEnum>(" \"myVal\":\"FIRST\"")
        assertNotNull(parsed)
        assertEquals(MyEnum.FIRST, parsed.myVal)
    

上述单元测试的响应是:

kotlin.TypeCastException: null cannot be cast to non-null type kotlin.String
    at com.beust.klaxon.EnumConverter.fromJson(EnumConverter.kt:23)
    at com.beust.klaxon.EnumConverter.fromJson(EnumConverter.kt:6)
    at com.beust.klaxon.JsonObjectConverter.retrieveKeyValues(JsonObjectConverter.kt:189)
    at com.beust.klaxon.JsonObjectConverter.initIntoUserClass(JsonObjectConverter.kt:67)
    at com.beust.klaxon.JsonObjectConverter.fromJson(JsonObjectConverter.kt:32)
    at com.beust.klaxon.DefaultConverter.fromJsonObject(DefaultConverter.kt:210)
    at com.beust.klaxon.DefaultConverter.fromJson(DefaultConverter.kt:32)
    at com.beust.klaxon.Klaxon.fromJsonObject(Klaxon.kt:296)
    at EnumTest.should deserialize null enum(EnumTest.kt:30)
    ...

错误的来源是https://github.com/cbeust/klaxon/blob/master/klaxon/src/main/kotlin/com/beust/klaxon/EnumConverter.kt#L23,其中 null 被强制转换为字符串。

【问题讨论】:

【参考方案1】:

我从 github 项目中复制了 EnumConverter 并使其可以为空,如果值为 null 则将第 23 行更改为返回 null,如下所示:

       val name = jv.inside as String? ?: return null

然后我为这些字段创建了一个注释并将转换器添加到解析器中。下面的 EnumConverter() 参考是我的副本,上面添加了 Elvis 运算符。

...
@Target(AnnotationTarget.FIELD)
annotation class NullableEnum

class WithEnum (
    @NullableEnum
    var myVal: MyEnum? = null
)

class EnumTest 
    @Test
    fun `should deserialize null enum`() 
        val parsed = Klaxon()
            .fieldConverter(NullableEnum::class, EnumConverter())
            .parse<WithEnum>(" \"myVal\":null")
        assertNotNull(parsed)
        assertNull(parsed.myVal)
    
...

【讨论】:

以上是关于Klaxon 解析空枚举的主要内容,如果未能解决你的问题,请参考以下文章

Klaxon 解析 null

为可空枚举动态构建谓词

Kotlin klaxon 解析谷歌方向 Api

如何处理枚举中空值的 InvalidFormatException

swift_枚举 | 可为空类型 | 枚举关联值 | 枚举递归 | 树的概念

如何使用 Klaxon 解析嵌套 JSON 并在 recyclerview 中显示?