У меня есть несколько объектов с URL-адресами в полях, например, таких как:
class A {
val url1 : URL
val url2 : URL
val urls : ArrayList<URL>
}
Я хотел бы заменить URL-адреса на Uri, но я использую Jackson и SQLite для сериализации объектов и сохранения их в БД , Поэтому, если я изменяю тип, я не могу получить сохраненные объекты.
Итак, я реализовал пользовательскую десериализацию следующим образом:
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"])
должны реализовать Custom Serialises тоже? Может быть, есть самый простой способ заменить URL на Uri?
РЕШЕНИЕ
Благодаря проверенному ответу я нашел решение своей проблемы: поэтому я использовал интерфейс MixIn с Custom Serializer и 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())
}
}
Затем я добавил UriMixIn везде, где это необходимо, например:
val jackson = jacksonObjectMapper()
jackson.addMixIn(Uri::class.java, UriMixIn::class.java)
Это решение работает как шарм! Большое спасибо за вашу помощь, хорошего дня!