【问题标题】:JSON deserialization using Jackson in Scala在 Scala 中使用 Jackson 进行 JSON 反序列化
【发布时间】:2014-05-18 08:41:15
【问题描述】:

我是杰克逊的新手。如果我在反序列化过程中未明确指定类类型,则在使用 Jackson 反序列化 JSON 字符串时遇到以下错误:

com.fasterxml.jackson.databind.JsonMappingException: Can not instantiate abstract type [simple type, class scala.runtime.Nothing$] (need to add/enable type information?)

有没有办法在 Jackson 中序列化/反序列化 JSON 而无需指定类类型?

这是我的测试代码:

import java.lang.reflect.{Type, ParameterizedType}
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.scala.DefaultScalaModule
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.`type`.TypeReference;
import org.junit._
import org.junit.Assert._

case class Person (name:String)
case class Address (city:String, state:String)

class JSONTest {

  @Test
  def jsonTest () = {

    val p = new Person ("Bob")

    val json = JacksonWrapper.serialize(p)
    println ("json= " + json)
    val obj = JacksonWrapper.deserialize[Person](json)
    println ("obj = " + obj)

    // fails since class type isn't explictly specified.  
    // is there a way to do it so that class type is automatically determined?
    val obj2 = JacksonWrapper.deserialize(json)
    println ("obj= " + obj2)


  }



}

//http://stackoverflow.com/questions/12591457/scala-2-10-json-serialization-and-deserialization
object JacksonWrapper {
  val mapper = new ObjectMapper()
  mapper.registerModule(DefaultScalaModule)

  def serialize(value: Any): String = {
    import java.io.StringWriter
    val writer = new StringWriter()
    mapper.writeValue(writer, value)
    writer.toString
  }

  def deserialize[T: Manifest](value: String) : T =
    mapper.readValue(value, typeReference[T])

  private [this] def typeReference[T: Manifest] = new TypeReference[T] {
    override def getType = typeFromManifest(manifest[T])
  }

  private [this] def typeFromManifest(m: Manifest[_]): Type = {
    if (m.typeArguments.isEmpty) { m.erasure }
    else new ParameterizedType {
      def getRawType = m.erasure
      def getActualTypeArguments = m.typeArguments.map(typeFromManifest).toArray
      def getOwnerType = null
    }
  }
}

【问题讨论】:

    标签: json scala serialization jackson


    【解决方案1】:

    您必须以某种方式提供类型信息。 Jackson 仅将对象的字段序列化为 JSON,它不会在任何地方存储有关类型的其他信息,因此对于您的 Person 类,JSON 可能如下所示:{ "name": "Bob"}。如果您不提供要反序列化为Person 实例的信息,杰克逊将无法知道该类型。您也可以使用字段 name 来创建另一个类,而 JSON 并没有说明您需要哪个类。这就是为什么您需要在反序列化时提供类型 - 在 Java 中通过传递 Class 类型的参数,在 Scala 中通过向 ObjectMapper 和朋友提供类型参数。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-06-11
      • 1970-01-01
      • 1970-01-01
      • 2015-02-28
      • 2021-12-13
      • 1970-01-01
      • 2019-01-20
      • 2013-08-04
      相关资源
      最近更新 更多