我只是通过使用Jackson JSON反序列化来破坏JVM类型的安全性吗?

bru*_*ito 5 json jvm scala type-safety jackson-module-scala

这就是我得到的:

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)
Run Code Online (Sandbox Code Playgroud)

同时,这甚至不会建立:

val bad: Option[Int] = "AB"
Run Code Online (Sandbox Code Playgroud)

显然这里有问题。我在项目中使用的版本:

scalaVersion:=“ 2.11.6”

libraryDependencies + =“ com.fasterxml.jackson.module”%“ jackson-module-scala_2.11”%“ 2.7.3”

Ale*_*nov 3

不,这不会破坏JVM类型安全。JVM 不支持泛型,就其类型而言idis Option, not Option[Int]。为了破坏类型安全,你必须得到一个不是一个TestClass的。idOption

反射和强制类型转换肯定会破坏 Java 和 Scala 的类型安全性,而且它们也应该这样做。

要在 Jackson 中正确反序列化泛型,您需要提供其他信息(请参阅http://wiki.fasterxml.com/JacksonFAQ#Deserializing_Generic_types),并且 jackson-module-scala 允许 Scala 编译器提供它:

您还可以混合 ScalaObjectMapper(实验性)来获得丰富的包装器,自动将 scala 清单直接转换为 TypeReferences 供 Jackson 使用:

val mapper = new ObjectMapper() with ScalaObjectMapper
mapper.registerModule(DefaultScalaModule)
val myMap = mapper.readValue[Map[String,Tuple2[Int,Int]]](src)
Run Code Online (Sandbox Code Playgroud)

我不知道它是否会自动防止您遇到的问题。