假设有一个接口和2个(或更多)实现:
interface IRunnable {
fun run()
}
class Horse : IRunnable {
override fun run() { println("horse running") }
}
class Dog : IRunnable {
override fun run() { println("dog running") }
}
我想实现用于网络传输的最简洁的JSON,即,对于Horse,{"runnable":"H"}
和对于Dog,{"runnable":"D"}
如果我无法修改接口和实现,我想将接口/实现序列化为JSON,根据Kotlin的文档,我必须编写custom serializer并使用{{ 1}}实现目标。
假设只有SerializersModule
和Horse
实现Dog
,这就是我所做的:
IRunnable
但是当我尝试将class RunnableSerializer : KSerializer<IRunnable> {
override val descriptor: SerialDescriptor
get() = StringDescriptor.withName("runnable")
override fun serialize(encoder: Encoder,obj: IRunnable) {
val stringValue = when (obj) {
is Horse -> { "H" }
is Dog -> { "D" }
else -> { null }
}
stringValue?.also {
encoder.encodeString(it)
}
}
override fun deserialize(decoder: Decoder): IRunnable {
return decoder.decodeString().let { value ->
when(value) {
"H" -> Horse()
"D" -> Dog()
else -> throw RuntimeException("invalid $value")
}
}
}
}
转换为JSON时...
Horse
它输出错误:
class RunnableTest {
private val logger = KotlinLogging.logger { }
@ImplicitReflectionSerializer
@Test
fun testJson() {
val module1 = serializersModuleOf(IRunnable::class,RunnableSerializer())
Json(context = module1).stringify(IRunnable::class.serializer(),Horse()).also {
logger.info("json = {}",it)
}
}
}
如何实现类似
在这种情况下是kotlinx.serialization.SerializationException:
Can't locate argument-less serializer for class IRunnable. For generic classes,such as lists,please provide serializer explicitly.
还是{"runnable":"H"}
?
谢谢。
环境:
{"runnable":"D"}
已更新,完整的错误消息:
<kotlin.version>1.3.60</kotlin.version>
<serialization.version>0.14.0</serialization.version>