This is what I got:
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.scala.DefaultScalaModuleobject
AppStart extends App {
val mapper = new ObjectMapper()
mapper.registerModule(DefaultScalaModule)
val json = """{"id":"AB","stuff":"whatever"}"""
val obj = mapper.readValue(json, classOf[TestClass])
println(obj.id.get) // prints AB !!!
}
case class TestClass(id: Option[Int] = None, stuff: Option[String] = None)
At the same time, this does not even build:
val bad: Option[Int] = "AB"
There is clearly something wrong here. Versions that I am using in project:
scalaVersion := "2.11.6"
libraryDependencies += "com.fasterxml.jackson.module" % "jackson-module-scala_2.11" % "2.7.3"
No, this doesn't break JVM type safety. JVM doesn't support generics, so far as it's concerned the type of id
is Option
, not Option[Int]
. To break type safety, you'd have to get a TestClass
whose id
is not an Option
.
Reflection and casting certainly break Java's and Scala's type safety, and they are supposed to.
To deserialize generics properly in Jackson, you need to supply additional information (see http://wiki.fasterxml.com/JacksonFAQ#Deserializing_Generic_types) and jackson-module-scala allows Scala compiler to supply it:
You can also mixin ScalaObjectMapper (experimental) to get rich wrappers that automatically convert scala manifests directly into TypeReferences for Jackson to use:
val mapper = new ObjectMapper() with ScalaObjectMapper mapper.registerModule(DefaultScalaModule) val myMap = mapper.readValue[Map[String,Tuple2[Int,Int]]](src)
I don't know if it'll automatically prevent the issue you have as well.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With