从 Jackson-Module-Scala 2.4 迁移到 2.5
Migrating from Jackson-Module-Scala 2.4 to 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 并使反序列化正常工作?
我遇到了类似的问题,只是升级到 jackson-module-scala 2.5.2 就解决了。
可能与:
https://github.com/FasterXML/jackson-module-scala/issues/189
我成功地使用 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 并使反序列化正常工作?
我遇到了类似的问题,只是升级到 jackson-module-scala 2.5.2 就解决了。
可能与: https://github.com/FasterXML/jackson-module-scala/issues/189