从Jackson-Module-Scala 2.4迁移到2.5

时间:2015-03-15 21:41:46

标签: json scala serialization jackson jackson-modules

我正在使用jackson-module-scala 2.4成功使用下面的包装器来序列化和反序列化各种复杂对象。当更改为jackson-module-scala 2.5时,许多反序列化(JSON到对象)都会失败。例如,以下简单列表的反序列化失败。

  val myList = MyListClass(List(1,2,3,4))
  val myListJson = "{\n  \"myList\" : [ 1, 2, 3, 4 ]\n}"

  // This test succeeds with Jackson 2.5
  test("Serialize List object to JSON string") {
    assertResult(myListJson) { serialize(myList) }
  }

  // This test *fails* with Jackson 2.5
  test("Deserialize JSON string to List") {
    assertResult(myList) { deserialize[MyListClass](myListJson) }
  }

错误消息:

Deserialize JSON string to List *** FAILED ***
com.fasterxml.jackson.databind.JsonMappingException: Argument #0 of constructor [constructor for java.util.LinkedHashMap, annotations: [null]] has no property name annotation; must have name when multiple-parameter constructor annotated as Creator
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:267)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCacheValueDeserializer(DeserializerCache.java:242)
at com.fasterxml.jackson.databind.deser.DeserializerCache.findValueDeserializer(DeserializerCache.java:143)
at com.fasterxml.jackson.databind.DeserializationContext.findNonContextualValueDeserializer(DeserializationContext.java:429)
at com.fasterxml.jackson.databind.deser.std.UntypedObjectDeserializer._findCustomDeser(UntypedObjectDeserializer.java:125)
at com.fasterxml.jackson.databind.deser.std.UntypedObjectDeserializer.resolve(UntypedObjectDeserializer.java:105)
at com.fasterxml.jackson.module.scala.deser.UntypedObjectDeserializer.resolve(UntypedObjectDeserializerModule.scala:23)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:293)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCacheValueDeserializer(DeserializerCache.java:242)
at com.fasterxml.jackson.databind.deser.DeserializerCache.findValueDeserializer(DeserializerCache.java:143)
...
Cause: java.lang.IllegalArgumentException: Argument #0 of constructor [constructor for java.util.LinkedHashMap, annotations: [null]] has no property name annotation; must have name when multiple-parameter constructor annotated as Creator
at com.fasterxml.jackson.databind.deser.BasicDeserializerFactory._addDeserializerConstructors(BasicDeserializerFactory.java:508)
at com.fasterxml.jackson.databind.deser.BasicDeserializerFactory._constructDefaultValueInstantiator(BasicDeserializerFactory.java:325)
at com.fasterxml.jackson.databind.deser.BasicDeserializerFactory.findValueInstantiator(BasicDeserializerFactory.java:258)
at com.fasterxml.jackson.databind.deser.BasicDeserializerFactory.createMapDeserializer(BasicDeserializerFactory.java:1099)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer2(DeserializerCache.java:382)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer(DeserializerCache.java:354)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:262)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCacheValueDeserializer(DeserializerCache.java:242)
at com.fasterxml.jackson.databind.deser.DeserializerCache.findValueDeserializer(DeserializerCache.java:143)
at com.fasterxml.jackson.databind.DeserializationContext.findNonContextualValueDeserializer(DeserializationContext.java:429)

这是包装器:

import com.fasterxml.jackson.databind.{DeserializationFeature, SerializationFeature, ObjectMapper}
import com.fasterxml.jackson.module.scala.experimental.ScalaObjectMapper
import com.fasterxml.jackson.module.scala.DefaultScalaModule
import com.fasterxml.jackson.databind.module.SimpleModule
import com.fasterxml.jackson.core.Version

/**
 * Based on: https://coderwall.com/p/o--apg/easy-json-un-marshalling-in-scala-with-jackson
 */
object JacksonWrapper {
  private val dateFormat = new java.text.SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")

  val module = new SimpleModule("CustomJson", Version.unknownVersion())
  module.addSerializer(classOf[BigInt], new BigIntSerializer)
  module.addDeserializer(classOf[BigInt], new BigIntDeserializer)

  val mapper = new ObjectMapper() with ScalaObjectMapper
  mapper.registerModule(DefaultScalaModule)
  mapper.setDateFormat(dateFormat)
  mapper.registerModule(module)
  mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
  mapper.enable(SerializationFeature.INDENT_OUTPUT); //Enable pretty printing

  def serialize(value: Map[Symbol, Any]): String = {
    serialize(value map { case (k,v) => k.name -> v})
  }

  def serialize(value: Any): String = {
    mapper.writeValueAsString(value)
  }

  def toMap[V](json:String)(implicit m: Manifest[V]) = deserialize[Map[String,V]](json)

  def deserialize[T](json: String)(implicit m : Manifest[T]): T = {
    mapper.readValue[T](json)
  }
}

如何迁移到Jackson 2.5并使反序列化工作?

1 个答案:

答案 0 :(得分:3)

我遇到了类似的问题,只是升级到jackson-module-scala 2.5.2解决了它。

它可能与以下内容有关: https://github.com/FasterXML/jackson-module-scala/issues/189