En utilisant jackson-module-Scala, j'essaie de sérialiser et de désérialiser un objet avec une carte interne en utilisant un long comme clé, mais le Jackson sérialise la clé comme Chaîne et ne la désérialise pas en tant qu'Ignorer le type défini dans la Classe. Est-ce un BUG? Est-ce que je fais quelque chose de mal?jackson-module-scala serialize/deserialize Longues clés dans Map as Strings
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.scala.DefaultScalaModule
import com.fasterxml.jackson.module.scala.experimental.ScalaObjectMapper
case class InnerMap(map: Map[Long, Long])
object CrazyJackson {
def main(args: Array[String]): Unit = {
val mapper = new ObjectMapper() with ScalaObjectMapper
mapper.registerModule(DefaultScalaModule)
val innerMap = InnerMap(Map(1L->1L))
val serialized = mapper.writeValueAsString(innerMap)
val newObj = mapper.readValue(serialized, classOf[InnerMap])
println(serialized) // Why the key is serialized as a String?
println(innerMap)
println(newObj)
assert(newObj == innerMap)
}
}
assert échoue et la sortie du println (sérialisés) déclaration est:
{"map":{"1":1}}
Il est étrange que l'impression newobj et innerMap est le même:
InnerMap(Map(1 -> 1))
InnerMap(Map(1 -> 1))
Comme @ Varren dit, le problème est vraiment dans l'affirmation. Mais:
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.scala.DefaultScalaModule
import com.fasterxml.jackson.module.scala.experimental.ScalaObjectMapper
import org.scalatest.FunSuite
class CrazyJacksonTest extends FunSuite {
test("test json comparision") {
val mapper = new ObjectMapper() with ScalaObjectMapper
mapper.registerModule(DefaultScalaModule)
val innerMap = InnerMap(Map(1L->1L))
val serialized = mapper.writeValueAsString(innerMap)
val newObj = mapper.readValue(serialized, classOf[InnerMap])
assert(newObj.map == innerMap.map)
}
}
Le résultat assert:
Map("1" -> 1) did not equal Map(1 -> 1)
ScalaTestFailureLocation: CrazyJacksonTest$$anonfun$1 at (CrazyJacksonTest.scala:17)
Expected :Map(1 -> 1)
Actual :Map("1" -> 1)
Je suis perdu! La carte doit être une Carte [Long, Long]!
Je dois utiliser cette version en raison de dépendances Spark:
- Scala 2.11.11
- jackson-module-scala 2.6.5 et tester aussi avec la version 2.9.1 avec le même résultat.
Autres infos:
Donc, le problème est avec l'assert. Je pensais que les classes de cas implémentent equals et hashCode. En fait, pourquoi "assert (InnerMap (Map (1L-> 1L)) == InnerMap (Map (1L-> 1L)))" ok? – angelcervera
S'il vous plaît, pouvez-vous vérifier mon nouvel exemple? Il me manque quelque chose. Comment est-il possible que l'assertion gère l'objet interne comme Map [String, Long] si la classe de cas est définie comme Map [Long, Long] – angelcervera
Le lien vers "Comment comparer les objets pour l'égalité dans Scala?" est un cas différent, car il s'agit de comparer des classes et non des classes de cas. – angelcervera