Using Jackson to (De)-serialize a Scala Case Class

Found a solution that works with jackson and scala case classes.

I used a scala module for jackson - jackson-module-scala.

libraryDependencies ++= Seq(
 "com.fasterxml.jackson.core" % "jackson-databind" % "2.5.3",
 "com.fasterxml.jackson.module" %% "jackson-module-scala" % "2.2.2"
)

I had to annotate fields in my case class with @JsonProperty.

This is what my case class looks like:

case class Person(@JsonProperty("FName") FName: String, @JsonProperty("LName") LName: String)

And this is how I deserialize:

val objectMapper = new ObjectMapper() with ScalaObjectMapper
objectMapper.registerModule(DefaultScalaModule)
val str = """{"FName":"Mad", "LName": "Max"}"""
val name:Person = objectMapper.readValue[Person](str)

Serialization is easier:

val out = new ByteArrayOutputStream()
objectMapper.writeValue(out, name)
val json = out.toString

Would like to clarify that I am using

com.fasterxml.jackson.databind.ObjectMapper

In the question, it seems he is using

org.codehaus.jackson.map.ObjectMapper 

which won't work with ScalaObjectMapper.


Based on Priyank Desai's answer I have created a generic function to convert json string to case class

import com.fasterxml.jackson.annotation.JsonProperty
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.scala.DefaultScalaModule
import com.fasterxml.jackson.module.scala.experimental.ScalaObjectMapper

def jsonToType[T](json:String)(implicit m: Manifest[T]) :T = {
   val objectMapper = new ObjectMapper() with ScalaObjectMapper
   objectMapper.registerModule(DefaultScalaModule)
   objectMapper.readValue[T](json)
}

Usage:

case class Person(@JsonProperty("name") Name:String, @JsonProperty("age") Age:Int)

val personName = jsonToType[Person](jsonString).name

Jackson is expecting your class to be a JavaBean, which means its expects the class to have a getX() and/or setX() for every property.

Option 1

You can create JavaBean classes in Scala using the annotation BeanProperty.

Example

case class Person(
   @BeanProperty val name: String, 
   @BeanProperty val age: Int, 
   @BeanProperty val hobbies: Option[String]
)

In this case a val will mean only a getter is defined. If you want setters for deserialization you defined the properties as var.

Option 2

While option 1 will work, if you really want to use Jackson there are wrappers that allow it to deal with Scala classes like FasterXML's scala module which might be a better approach. I haven't used it as I've just been using the Json library built in to play.