Миграция с Jackson-Module-Scala 2.4 на 2.5

Я успешно использую 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 и заставить работать десериализацию?


person jans    schedule 15.03.2015    source источник


Ответы (1)


Я столкнулся с аналогичной проблемой, и простое обновление до jackson-module-scala 2.5.2 решило ее.

Вероятно, это связано с: https://github.com/FasterXML/jackson-module-scala/issues/189

person shimarin    schedule 13.04.2015
comment
Да, это решено в версии 2.5.2, но соответствующий билет проблемы — github.com /FasterXML/jackson-module-scala/issues/196 - person jans; 13.04.2015