在Scala 2.10.6中,使用json4s 3.2.11,我现在受约束,使用以下代码:
object Thing1 extends Enumeration {
type Thing1 = Value
val A = Value(0, "A")
val B = Value(1, "B")
}
object Thing2 extends Enumeration {
type Thing2 = Value
val A = Value(0, "A")
val B = Value(1, "B")
val C = Value(2, "C")
}
case class ThingHolder(thing1: Thing1, thing2: Thing2)
class ThingSpec extends FlatSpec with Matchers {
"desrialized" should "match original" in {
import org.json4s.native.Serialization.writePretty
implicit val formats = DefaultFormats + new EnumNameSerializer(Thing1) + new EnumNameSerializer(Thing2)
val original = ThingHolder(Thing1.A, Thing2.C)
println(original)
val serialized = writePretty(original)
println(serialized)
val jValue = JsonParser.parse(serialized)
val deserialized = jValue.camelizeKeys.extract[ThingHolder]
println(deserialized)
println(deserialized.thing1)
deserialized should be(original)
}
}
结果:
ThingHolder(A,C)
{
"thing1":"A",
"thing2":"C"
}
ThingHolder(A,C)
A
ThingHolder(A,C) was not equal to ThingHolder(A,C)
这与Enumeration有关,但不是其他类型,例如String。如果case类只有一个Enumeration,它可以正常工作。这是为什么?我可以通过使用字符串反序列化为case类,然后按照我希望的方式映射到case类来纠正这个问题。有没有办法哄骗json4s直接反序列化,以便反序列化的对象与原始对象匹配?
编辑:
这是我提到的用于映射的黑客攻击:
case class ThingHolderSerialized(thing1: String, thing2: String)
...
val deserialized = jValue.camelizeKeys.extract[ThingHolderSerialized]
val reconstituted = ThingHolder(Thing1.withName(deserialized.thing1), Thing2.withName(deserialized.thing2))
编辑:
实际上,不需要单独的序列化程序类:
val deserialized = jValue.camelizeKeys.extract[ThingHolder]
val reconstituted = ThingHolder(Thing1.withName(deserialized.thing1.toString), Thing2.withName(deserialized.thing2.toString))
编辑:
似乎没有正确反序列化的东西,因为这也构建了匹配的重构对象:
val reconstituted = deserialized.copy(thing1 = Thing1.withName(deserialized.thing1.toString))
但不是这样:
val reconstituted = deserialized.copy(thing2 = Thing2.withName(deserialized.thing2.toString))
答案 0 :(得分:0)
我把它作为一个解决方案,用于需要在多个Enumerations存在的情况下支持json4s案例类反序列化的人。这不是我正在寻找的答案,但在此期间有效:
object Thing1 extends Enumeration {
type Thing1 = Value
val A = Value(0, "A")
val B = Value(1, "B")
}
object Thing2 extends Enumeration {
type Thing2 = Value
val A = Value(0, "A")
val B = Value(1, "B")
val C = Value(2, "C")
}
case class ThingHolder(thing1: Thing1, thing2: Thing2)
class ThingSpec extends FlatSpec with Matchers {
"reconstituted" should "match original" in {
import org.json4s.native.Serialization.writePretty
implicit val formats = DefaultFormats + new EnumNameSerializer(Thing1) + new EnumNameSerializer(Thing2)
val original = ThingHolder(Thing1.A, Thing2.C)
println(original)
val serialized = writePretty(original)
println(serialized)
val jValue = JsonParser.parse(serialized)
val deserialized = jValue.camelizeKeys.extract[ThingHolder]
println(deserialized)
val reconstituted = deserialized.copy(thing1 = Thing1.withName(deserialized.thing1.toString))
reconstituted should be(original)
}
}
关键是我们正在构建reconstituted
的行。我们制作副本,并在此过程中,将thing1转换为字符串并返回枚举。幸运的是,toString在没有正确反序列化字段的情况下工作。