I'm trying to serialize/deserialize a Scala class to JSON using Jackson ObjectMapper. The serialization works fine, but I was getting type exceptions trying to read the JSON back in. I fixed most of those by adding appropriate annotations, but it's not working for my Map members... it seems like Jackson is trying to treat the keys in the JSON object as properties in a class instead of keys in a map. (I believe this is different than other questions like this one since they are calling readValue
on the map contents directly.)
Here's my ObjectMapper setup:
val mapper = new ObjectMapper() with ScalaObjectMapper
mapper.registerModule(DefaultScalaModule)
Here's what my annotated class and member look like:
@JsonInclude(JsonInclude.Include.NON_DEFAULT)
class MyClass extends Serializable {
@JsonDeserialize(
as = classOf[mutable.HashMap[String, Long]],
keyAs = classOf[java.lang.String],
contentAs = classOf[java.lang.Long]
)
val counts = mutable.Map.empty[String, Long]
}
If I give it some JSON like:
{"counts":{"foo":1,"bar":2}}
And read it with mapper.readValue[MyClass](jsonString)
I get an exception like UnrecognizedPropertyException: Unrecognized field "foo" (class mutable.HashMap), not marked as ignorable
.
I tried adding DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES
to my mapper configuration but that didn't seem to do anything in this case, and I'm not sure that kind of global setting is desirable.
How do I convince Jackson to treat the strings "foo" and "bar" as keys in the map member field and not as properties in the HashMap class? It seems to have done the right thing automatically writing it out.
Also worth noting: the deserialization appears to work fine in a quick out/in unit test to a temp file or a string variable, but not when I try to run the whole application and it reads the JSON its previously written. I don't know why it seems to work in the test, as far as I know it's making the same readValue
call.