I have some objects with URLs in fields for example like this :
class A {
val url1 : URL
val url2 : URL
val urls : ArrayList<URL>
}
I would like to replace URLs by Uri, but I've use Jackson and SQLite to serialise objects and store them in DB. So if I change the type, I can't retrieve stored objects.
So, I've implemented Custom Deserialise like that :
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
}
}
And then I've added UriDeserializer for fields in my class :
class A {
@JsonDeserialize(using = UriDeserializer::class)
val url1 : Uri
@JsonDeserialize(using = UriDeserializer::class)
val url2 : Uri
@JsonDeserialize(using = UriArrayDeserializer::class)
val urls : ArrayList<Uri>
}
With this code, I can deserialize my old objects, but now I can't serialise new ones, I get this error :
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Direct self-reference leading to cycle (through reference chain: com.package.A["url2"]->android.net.Uri$StringUri["canonicalUri"])
Do I have to implement Custom Serialises too ? Maybe there is a simplest way to replace URL by Uri ?
SOLUTION
Thanks to the checked answer, I've found the solution to my problem : So I've used a MixIn interface with Custom Serializer and Deserializer.
@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())
}
}
Then, I've added UriMixIn wherever it needed like :
val jackson = jacksonObjectMapper()
jackson.addMixIn(Uri::class.java, UriMixIn::class.java)
This solution works like a charm ! Thanks a lot for your help, have a great day !