【问题标题】:Serializing sequences of AnyVal with json4s使用 json4s 序列化 AnyVal 的序列
【发布时间】:2015-07-10 15:37:35
【问题描述】:

尝试在 scala 中使用 json4s 序列化 AnyVal 序列时遇到问题。

这是使用 FunSuite 进行的测试,重现了该问题:

  import org.json4s._
  import org.json4s.jackson.JsonMethods._
  import org.json4s.jackson.Serialization._
  import org.scalatest.{FunSuite, Matchers}

  case class MyId(id: String) extends AnyVal

  case class MyModel(ids: Seq[MyId])

  class AnyValTest extends FunSuite with Matchers {

    test("should serialize correctly") {

      implicit val formats = DefaultFormats

      val model = MyModel(Seq(MyId("1"), MyId("2")))
      val text = write(model)

      parse(text).extract[MyModel] shouldBe model
    }
  }

尝试从 JValue 中提取 MyModel 时测试失败,因为它无法为 ids 字段找到合适的值。

我注意到 AnyVal 在直接使用时工作正常,但与以下类似:

case class AnotherModel(id: MyId)

然后我就可以正确序列化和反序列化了。

【问题讨论】:

  • 你觉得case class MyId(id: String) extends AnyVal有什么意义吗?如果你想扩展一些行为,也许使用 Traits 会更好,你不这么认为吗?

标签: json scala serialization deserialization json4s


【解决方案1】:

我知道这个问题已经有一年了,但我遇到了同样的问题。写下我所做的,以防它帮助别人。您将需要一个自定义序列化程序。

case class Id(asString: String) extends AnyVal

class NotificationSerializer extends CustomSerializer[Id](format ⇒ (
  {case JString(s) => Id(s)},
  {case Id(s) => JString(s)}))

如果没有上述序列化,您的 JSON 将类似于

{"ids":[[{"asString":"testId1"},{"asString":"testId2"}]]}

我不完全确定为什么 AnyVal 案例类序列化在它是另一个案例类的一部分但不是独立的情况下可以正常工作。我最好的猜测是这种行为是由于 JVM 对包含值类的数组的分配行为。请参阅 http://docs.scala-lang.org/overviews/core/value-classes.html 了解“何时需要分配”部分。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-05
    • 1970-01-01
    • 2015-01-27
    • 1970-01-01
    • 1970-01-01
    • 2014-08-18
    相关资源
    最近更新 更多