【发布时间】:2020-03-06 11:01:18
【问题描述】:
我在字段中有一些带有 URL 的对象,例如:
class A {
val url1 : URL
val url2 : URL
val urls : ArrayList<URL>
}
我想用 Uri 替换 URL,但我使用 Jackson 和 SQLite 来序列化对象并将它们存储在 DB 中。因此,如果我更改类型,我将无法检索存储的对象。
所以,我已经实现了这样的自定义反序列化:
class UriDeserializer : StdDeserializer<Uri>(Uri::class.java) {
override fun deserialize(p: JsonParser?, ctxt: DeserializationContext?): Uri {
return Uri.parse(p?.valueAsString)
}
}
class UriArrayDeserializer : StdDeserializer<ArrayList<Uri>>(ArrayList::class.java) {
override fun deserialize(p: JsonParser?, ctxt: DeserializationContext?): ArrayList<Uri> {
val uriArray = arrayListOf<Uri>()
p?.nextToken()
while (p?.currentToken != JsonToken.END_ARRAY) {
val uri = Uri.parse(p?.text)
uriArray.add(uri)
p?.nextToken()
}
return uriArray
}
}
然后我为班级中的字段添加了 UriDeserializer:
class A {
@JsonDeserialize(using = UriDeserializer::class)
val url1 : Uri
@JsonDeserialize(using = UriDeserializer::class)
val url2 : Uri
@JsonDeserialize(using = UriArrayDeserializer::class)
val urls : ArrayList<Uri>
}
使用此代码,我可以反序列化我的旧对象,但现在我无法序列化新对象,我收到此错误:
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Direct self-reference leading to cycle (through reference chain: com.package.A["url2"]->android.net.Uri$StringUri["canonicalUri"])
我是否也必须实现自定义序列化?也许有一种最简单的方法可以用 Uri 替换 URL ?
解决方案
感谢检查的答案,我找到了问题的解决方案:所以我使用了带有自定义序列化器和反序列化器的 MixIn 接口。
@JsonSerialize(using = UriSerializer::class)
@JsonDeserialize(using = UriDeserializer::class)
interface UriMixIn
class UriDeserializer : StdDeserializer<Uri>(Uri::class.java) {
override fun deserialize(p: JsonParser?, ctxt: DeserializationContext?): Uri {
return Uri.parse(p?.valueAsString)
}
}
class UriSerializer : StdSerializer<Uri>(Uri::class.java) {
override fun serialize(value: Uri?, gen: JsonGenerator?, provider: SerializerProvider?) {
gen?.writeString(value?.toString())
}
}
然后,我在需要的地方添加了 UriMixIn:
val jackson = jacksonObjectMapper()
jackson.addMixIn(Uri::class.java, UriMixIn::class.java)
这个解决方案就像一个魅力!非常感谢您的帮助,祝您有美好的一天!
【问题讨论】:
标签: java android kotlin jackson