I have the following Scala case class
:
case class InteractionPersona(
id: String,
geo: Option[(Option[String], Option[String], Option[String])])
Using Jackson, when I serialize an instance of the class:
val persona = InteractionPersona("123", Some((Some("canada"), None, None)))
val json = mapper.writeValueAsString(persona)
I receive the following JSON:
{"id": "123", "geo": ["canada", null, null]}
which is a perfectly valid representation for my needs. During deserialization though, I receive com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.lang.String out of VALUE_NULL token
:
val actual = mapper.readValue(json, classOf[InteractionPersona])
Apparently, null
is not an acceptable String
value, but since I'm deserializing to a Scala Option[String]
, null
should be represented as a None
value.
In How to deserialize Jackson Json NULL String to Date with JsonFormat, @wassgren suggested using a converter using the JsonDeserialize
annotation, and after reading documentation, I chose to use the contentUsing
option:
case class InteractionPersona(
id: String,
@JsonDeserialize(contentUsing = classOf[GeoConverter])
geo: Option[(Option[String], Option[String], Option[String])])
class GeoConverter extends JsonDeserializer[Option[(Option[String], Option[String], Option[String])]] {
override def deserialize(jp: JsonParser, ctxt: DeserializationContext): Option[(Option[String], Option[String], Option[String])] = {
throw new RuntimeException("tada")
}
}
Unfortunately, that code does not raise the expected exception. Attempting to use a contentConverter
also does not raise any exception:
@JsonDeserialize(contentConverter = classOf[GeoConverter])
class GeoConverter extends StdConverter[String, Option[String]] {
override def convert(value: String): Option[String] = {
throw new RuntimeException("tada")
}
}
How can I read an array of String objects and accept or transform null values?