这是我的代码:
class Foo<K>(
val foo: Bar<K>
)
class Bar<K>(
val bar: K
)
class Baz(
val baz: ByteArray
)
internal class BazSerializer : JsonSerializer<Baz>() {
override fun serialize(value: Baz, gen: JsonGenerator, serializers: SerializerProvider) {
gen.writeString(String(value.baz))
}
}
internal class BazDeserializer : JsonDeserializer<Baz>() {
override fun deserialize(p: JsonParser, ctxt: DeserializationContext): Baz {
return Baz(p.valueAsString.toByteArray())
}
}
val MAPPER = ObjectMapper()
.registerModule(
SimpleModule()
.addSerializer(Baz::class.java, BazSerializer())
.addDeserializer(Baz::class.java, BazDeserializer())
).registerKotlinModule()
}
我的自定义解串器/序列化器仅用于字节->字符串转换,因此可以在JSON中很好地显示。这是我的绿色测试:
@Test
fun `foo bar`() {
val type1 = "text"
val type2 = Baz("baz".toByteArray())
val fooStringOriginal = Foo(Bar(type1))
val fooByteArrayOriginal = Foo(Bar(type2))
// {"foo":{"bar":"text"}}
val s1 = MAPPER.writeValueAsString(fooStringOriginal)
// {"foo":{"bar":"baz"}}
val s2 = MAPPER.writeValueAsString(fooByteArrayOriginal)
val fooStringDeser = MAPPER.readValue<Foo<String>>(s1)
val fooByteArrayDeser = MAPPER.readValue<Foo<Baz>>(s2)
// {"foo":{"bar":"text"}}
val s11 = MAPPER.writeValueAsString(fooStringDeser)
// {"foo":{"bar":"baz"}}
val s21 = MAPPER.writeValueAsString(fooByteArrayDeser)
assertEquals(s1, s11)
assertEquals(s2, s21)
assertEquals(fooStringOriginal.foo.bar, fooStringDeser.foo.bar)
assertEquals(String(fooByteArrayDeser.foo.bar.baz), "baz")
assertTrue(fooByteArrayDeser.foo.bar is Baz)
}
现在让我们说,不是要在我的api上公开MAPPER对象,而是要向kt文件中添加序列化和反序列化方法,并在测试中使用这些方法:
fun <K> serialize(mapping: Foo<K>): String {
return MAPPER.writeValueAsString(mapping)
}
fun <K> deserialize(json: String): Foo<K> {
return MAPPER.readValue<Foo<K>>(json)
}
但是由于某种原因,kotlin没有收到我的Baz
,并认为这是HashMap
:
@Test
fun `failing foo bar`() {
val type1 = "text"
val type2 = Baz("baz".toByteArray())
val fooStringOriginal = Foo(Bar(type1))
val fooByteArrayOriginal = Foo(Bar(type2))
val s1 = serialize(fooStringOriginal)
val s2 = serialize(fooByteArrayOriginal)
val fooStringDeser = deserialize<String>(s1)
val fooByteArrayDeser = deserialize<Baz>(s2)
val s11 = serialize(fooStringDeser)
val s21 = serialize(fooByteArrayDeser)
assertEquals(s1, s11)
assertEquals(s2, s21)
assertEquals(fooStringOriginal.foo.bar, fooStringDeser.foo.bar)
assertEquals(String(fooByteArrayDeser.foo.bar.baz), "baz")
// ^^^^^ ERROR: java.lang.ClassCastException: java.lang.String cannot be cast to Baz
assertTrue(fooByteArrayDeser.foo.bar is Baz)
}
有人知道MAPPER.readValue<Foo<Baz>>
为何有效而deserialize<Baz>
无效(只是返回MAPPER.readValue<Foo<K>>
)的线索吗?
编辑:我不能使用内联修饰符,因为我希望从Java中调用它。