Простая библиотека Scala JSON для нерекурсивных классов
У меня есть классы дел, которые содержат только строки или коллекции строк и хотят преобразовать их в объекты 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
Большинство библиотек имеют специальную поддержку для классов дел, но, кажется, никогда не существует способа использовать его в сочетании с дополнительным полем типа для устранения неоднозначности изоморфных дел, и мне пришлось бы вернуться к более низкоуровневым описаниям.
До сих пор я пробовал спрей-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")
}
}
}
Для аргонавта я даже не мог понять, как сопоставить поле типа, так как 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 ответ
Я использую: 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"
Я надеюсь, что это может помочь.