用于非递归案例类的简单Scala JSON库

时间:2015-03-20 19:17:22

标签: json scala spray-json argonaut

我的案例类只包含字符串或字符串集合,并希望将它们转换为具有相应字段名称的JSON对象以及表示该类型的附加字段。

sealed trait Item
case class ProductX(a: String, b: String) extends Item
case class ProductY(a: String, b: String) extends Item
case class CollX(els: List[String]) extends Item
case class CollY(els: List[String]) extends Item

大多数lib都对case类有特殊支持,但似乎没有办法将它与其他类型字段一起使用来消除同构情况的歧义,我不得不回到更低级别的描述

到目前为止,我已经尝试过喷射json和argonaut,并且我的方式比我的简单使用场景更合理:

// spray-json

implicit object CollXJsonFormat extends RootJsonFormat[CollX] {
  def write(ss: CollX) = JsObject(
    "type" -> JsString("CollX"),
    "els"  -> JsArray(ss.els.map(JsString(_)): _*)
  )
  def read(value: JsValue) = {
    value.asJsObject.getFields("type", "els") match {
      case Seq(JsString("CollX"), JsArray(els)) =>
        CollX(els.toList.map({
          case JsString(s) => s
          case _ => throw new DeserializationException("JsString expected")
        }))
      case _ => throw new DeserializationException("CollX expected")
    }
  }
}

对于argonaut我甚至无法弄清楚如何匹配类型字段,因为DecodeResult没有过滤方法:

// argonaut

implicit def CollXCodec: CodecJson[CollX] =
  CodecJson(
    (px: CollX) =>
      ("type" := "CollX") ->:
      ("els" := px.els) ->:
      jEmptyObject,
    c => for {
      t <- (c --\ "type").as[String]
      els <- (c --\ "els").as[List[String]]
    } yield CollX(els))

是否有另一个可以更好地处理这个问题的库,或者是否有一些我忽略的库中的某些功能会大大减少样板?

1 个答案:

答案 0 :(得分:0)

我使用:net.liftweb效果非常好。

你可以用这种方式创建json。 例如,如果你有:

case class ABjsontemplate(a: String, b: String)

您可以像这样创建json:

net.liftweb.json.Serialization.write(ABjsontemplate("a", "b"))
SBT中的

libraryDependencies += "net.liftweb" %% "lift-json" % "3.0-M1"

我希望它可以提供帮助。