Klaxon parse null enum



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

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 被强制转换为字符串。

我从 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)
}
...

最新更新