Deserialize Scala map field from JSON using Jackson

jackson map deserializer
json map representation
scala jackson json to map
scala jackson json deserialize
scala parse json to map
scala jackson string to json
scala list to json jackson
jackson scala

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.

I made one simple test like this:

case class TestClass (counts: mutable.HashMap[String, Long])

And I converted it like:

val objectMapper = new ObjectMapper() with ScalaObjectMapper
objectMapper.registerModule(DefaultScalaModule)

val r3 = objectMapper.readValue("{\"counts\":{\"foo\":1,\"bar\":2}}", classOf[TestClass])

And apparently it works for me. Maybe it's something about the version you're using of Jackson, or Scala. Have you tried different versions of Jackson for example?

Deserialize Scala map field from JSON using Jackson, I'm trying to serialize/deserialize a Scala class to JSON using Jackson ObjectMapper. The serialization works fine, but I was getting type  ObjectMapper is Jackson's serialization mapper, which allows us to serialize our map and write it out as a pretty-printed JSON String, using the toString () method in String: "key" : "value" 3.2. Map<Object, String> Serialization. You can serialize a map containing a custom Java class with a few extra steps. Let's create a MyPair class to

Try jsoniter-scala and you will enjoy how it can be handy, safely, and efficient to parse and serialize JSON these days with Scala: https://github.com/plokhotnyuk/jsoniter-scala

One of it's crucial features is an ability to generate codecs in compile time and even print their sources. You will have no any runtime magic like reflection or byte code replacement that will affect your code.

Map Serialization and Deserialization with Jackson, 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  List, Seq, Array, Set and Map (note, keys of the Map must be strings: Map[String, _]) scala.Option; java.util.Date; Polymorphic Lists (see below) Recursive types; Serialization of fields of a class; Of course, you might already started asking how about more complicated use cases.

My problem was a race condition due to not using chaining in my mapper configuration singleton.

My old code was more like this:

private var mapper: ObjectMapper with ScalaObjectMapper = _

def getMapper: ObjectMapper with ScalaObjectMapper = {
  if (mapper == null) {
    mapper = new ObjectMapper() with ScalaObjectMapper
    mapper.registerModule(DefaultScalaModule)
    mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
  }
  mapper
}

As you can see, if one thread initializes the mapper, but hasn't yet disabled unknown properties failure, a second thread could return and use a mapper that hasn't had that flag set yet, which explains why I was seeing the error only some of the time.

The correct code uses chaining so that the mapper singleton is set with all of the configuration:

private var mapper: ObjectMapper = _

 def getMapper: ObjectMapper = {
   if (mapper == null) {
     mapper = new ObjectMapper()
       .registerModule(DefaultScalaModule)
       .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
   }
   mapper
 }

(I also removed the experimental ScalaObjectMapper mix-in.)

Mapping Nested Values with Jackson, In this article, we'll look at serialization and deserialization of Java maps case, let's create a Map<String, String> and serialize it to JSON: ? Thanks. Finally figured this out after breaking my head over numerous Scala json libraries that are not as performant or reliable as Jackson. Would have saved me a day or two of trying them all out (especially play json and json4s) if had found this earlier :-)

Easy JSON (un)marshalling in Scala with Jackson (Example), three ways to deserialize nested JSON values in Java using the Jackson library. we'll look at how to map nested values with Jackson to flatten out a Here, we use ObjectMapper's readTree to parse out the desired fields:. This quick tutorial will illustrate how to use Jackson 2 to deserialize JSON using a custom Deserializer. If you want to dig deeper and learn other cool things you can do with the Jackson 2 – head on over to the main Jackson tutorial. The article discusses Jackson's central ObjectMapper class, basic serialization and deserialization as well

Jackson ObjectMapper, A protip by jeroenr about scala, json, jackson, serialization, and fromJson[Map[​String,V]](json) def fromJson[T](json: String)(implicit m  A typical use case when working with JSON is to perform a transformation from one model into another. For example, we might want to parse a complex, densely nested object graph into a more straightforward model for use in another domain. In this quick article, we'll look at how to map nested values with Jackson to flatten out a complex data

Java and JSON – Jackson Serialization with ObjectMapper, Parsing JSON into Java objects is also referred to as to deserialize Java How Jackson ObjectMapper Matches JSON Fields to Java Fields By default Jackson maps the fields of a JSON object to fields in a Java object by  Using Jackson API for Map Deserialization We can use the ObjectMapper.readValue() method for converting a JSON text to a Map object. The following example demonstrates how to convert the JSON text to Map.

Comments
  • I'm using 2.8.x from the fasterxml (NOT codehaus) package naming.
  • Maybe try "com.fasterxml.jackson.module" %% "jackson-module-scala" % "2.9.4", or try using a case class, or instead of mapper.readValue[MyClass](jsonString), try using mapper.readValue(jsonString, classOf[MyClass]).
  • I think I had a race condition in my mapper (which I was using from a singleton)... note that I was setting features on the mapper after storing it; I switched to chaining the sets and added the ignore: mapper = new ObjectMapper().registerModule(DefaultScalaModule).disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)