我想不出使用组合器的好方法,因为那里的大多数方法都需要一种更直接的方法来将路径中的值映射到案例类字段。
这是一个适用于{"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
是棘手的部分,因为我们不习惯将路径名拉入案例类。我们可以validate
将对象作为JsObject
第一个对象,然后collect
只有与我们正在寻找的确切结构匹配的对象(只有一个键值对,其中值为 a 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"}