4

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?

Community
  • 1
  • 1
François Beausoleil
  • 16,265
  • 11
  • 67
  • 90
  • Using Jackson 2.3.5, because that is the most recent version with pre-built binaries for the Scala module for the 2.9.1 series of Scala. – François Beausoleil Apr 19 '15 at 02:36
  • 1
    Do you use DefaultScalaModule? https://github.com/FasterXML/jackson-module-scala – sap1ens Apr 19 '15 at 03:47
  • There is an overkill: use json4s and write rules for your own serializer. (lik here, for example: http://stackoverflow.com/questions/29710814/scala-liftweb-serializing-json) – Nikita Apr 19 '15 at 08:38
  • 1
    I do register the `DefautlScalaModule`. – François Beausoleil Apr 19 '15 at 11:00
  • I've used the DefaultScalaModule and I find that it doesn't handle null values (i.e. ones that are declared but have no value e.g.: foo:) Can not deserialize instance of java.lang.String out of NOT_AVAILABLE token – Andrew Norman Feb 23 '16 at 01:49

0 Answers0