Scala key/value 案例 class 到 Json
Scala key/value case class to Json
给定以下情况class:
case class ValueItem(key: String, value: String)
和以下 json 格式化程序:
implicit val valueItemFormat: Format[ValueItem] = (
(__ \ "key").format[String] and
(__ \ "value").format[String])(ValueItem.apply, unlift(ValueItem.unapply))
json ValueItem 实例的表示,如
ValueItem("fieldname", "fieldValue")
是
{ "key" : "fieldName" , "value" : "fieldValue" }
我想知道如何在像
这样的平面key/value序列化中获得json
{ "fieldName" : "fieldValue" }
我想不出使用组合器执行此操作的好方法,因为那里的大多数方法都需要更直接的方法来将路径中的值映射到 case class 字段。
这是一个适用于 {"fieldName" : "fieldValue"}
.
等对象的解决方案
import play.api.libs.json._
import play.api.data.validation.ValidationError
implicit val fmt: Format[ValueItem] = new Format[ValueItem] {
def reads(js: JsValue): JsResult[ValueItem] = {
js.validate[JsObject].collect(ValidationError("Not a key-value pair")) {
case JsObject(Seq((key, str: JsString))) => ValueItem(key, str.value)
}
}
def writes(v: ValueItem): JsValue = Json.obj(v.key -> v.value)
}
我已求助于手动定义 reads
和 writes
,如您所见。 Reads
是棘手的部分,因为我们不习惯将路径名拉入大小写 classes。我们可以 validate
对象作为 JsObject
首先,然后 collect
只有匹配我们正在寻找的确切结构的对象(只有一个键值对,其中值是 JsString
). Writes
更直接,因为 Json.obj
可以完全满足我们的要求。
进行中:
scala> Json.parse(""" { "fieldName" : "fieldValue" } """).validate[ValueItem]
res0: play.api.libs.json.JsResult[ValueItem] = JsSuccess(ValueItem(fieldName,fieldValue),)
scala> val item = ValueItem("myKey", "myValue")
item: ValueItem = ValueItem(myKey,myValue)
scala> Json.toJson(item)
res2: play.api.libs.json.JsValue = {"myKey":"myValue"}
Play 发布了它的模块,用于处理 JSON 独立于 Play Framework,Play WS
写了一篇关于阅读 JSON 案例 类 的博客 post,但写的内容非常相似。在 http://pedrorijo.com/blog/scala-json/
查看
使用大小写 类 和 Play WS(已包含在 Play Framework 中)您可以使用简单的 one-liner 在 json 和大小写 类 之间进行大小写转换隐式
case class User(username: String, friends: Int, enemies: Int, isAlive: Boolean)
object User {
implicit val userJsonFormat = Json.format[User]
}
给定以下情况class:
case class ValueItem(key: String, value: String)
和以下 json 格式化程序:
implicit val valueItemFormat: Format[ValueItem] = (
(__ \ "key").format[String] and
(__ \ "value").format[String])(ValueItem.apply, unlift(ValueItem.unapply))
json ValueItem 实例的表示,如
ValueItem("fieldname", "fieldValue")
是
{ "key" : "fieldName" , "value" : "fieldValue" }
我想知道如何在像
这样的平面key/value序列化中获得json{ "fieldName" : "fieldValue" }
我想不出使用组合器执行此操作的好方法,因为那里的大多数方法都需要更直接的方法来将路径中的值映射到 case class 字段。
这是一个适用于 {"fieldName" : "fieldValue"}
.
import play.api.libs.json._
import play.api.data.validation.ValidationError
implicit val fmt: Format[ValueItem] = new Format[ValueItem] {
def reads(js: JsValue): JsResult[ValueItem] = {
js.validate[JsObject].collect(ValidationError("Not a key-value pair")) {
case JsObject(Seq((key, str: JsString))) => ValueItem(key, str.value)
}
}
def writes(v: ValueItem): JsValue = Json.obj(v.key -> v.value)
}
我已求助于手动定义 reads
和 writes
,如您所见。 Reads
是棘手的部分,因为我们不习惯将路径名拉入大小写 classes。我们可以 validate
对象作为 JsObject
首先,然后 collect
只有匹配我们正在寻找的确切结构的对象(只有一个键值对,其中值是 JsString
). Writes
更直接,因为 Json.obj
可以完全满足我们的要求。
进行中:
scala> Json.parse(""" { "fieldName" : "fieldValue" } """).validate[ValueItem]
res0: play.api.libs.json.JsResult[ValueItem] = JsSuccess(ValueItem(fieldName,fieldValue),)
scala> val item = ValueItem("myKey", "myValue")
item: ValueItem = ValueItem(myKey,myValue)
scala> Json.toJson(item)
res2: play.api.libs.json.JsValue = {"myKey":"myValue"}
Play 发布了它的模块,用于处理 JSON 独立于 Play Framework,Play WS
写了一篇关于阅读 JSON 案例 类 的博客 post,但写的内容非常相似。在 http://pedrorijo.com/blog/scala-json/
查看使用大小写 类 和 Play WS(已包含在 Play Framework 中)您可以使用简单的 one-liner 在 json 和大小写 类 之间进行大小写转换隐式
case class User(username: String, friends: Int, enemies: Int, isAlive: Boolean)
object User {
implicit val userJsonFormat = Json.format[User]
}