在以下功能中,我正在解析 json
。我想返回JsError
,其中描述了json
中的所有错误(如果有(。但是我无法弄清楚如何在不使用var
的情况下继续更改JsError
。我正在寻找更多functional
编写代码的方式。
implicit object PQReads extends Reads[PQ] {
def reads(json:JsValue):JsResult[PQ] = {
val id = (json "id").asOpt[UUID]
val d = (json "d").asOpt[String]
val h = (json "h").asOpt[List[String]]
val i = (json "i").asOpt[List[String]]
//HERE I WANT TO ADD LOGIC TO CHECK THAT ALL THE OPTIONS ARE DEFINED.
//THE ONES WHICH ARE NONE SHOULD BE INDICATED BACK IN JSERROR
// (EG D AND I FIELDS ARE MISSING). HOW DO I DO THIS WITHOUT
// USING VAR TYPE FOR JSERROR.
//IF ALL THE FIELDS ARE PRESENT THEN I'LL RETURN PQ INSTANCE IN JSSUCCESS
}
我已经有一段时间没有使用过游戏,但是我认为您不必手动阅读。
当您有case class PQ(id: UUID, d :String, h: List[String], i: List[String])
时,您可以简单地编写implicit val pqReads = Json.reads[PQ]
。有关自动映射的文档,请参见此处。
但是,如果您真的想自己做,请看阅读组合。
implicit val pqReads: Reads[PQ] = (
(JsPath "id").read[UUID] and
(JsPath "d").read[String] and
(JsPath "h").read[List[String]] and
(JsPath "i").read[List[String]]
)(PQ.apply _)
转换,
val validJson = Json.parse("""
{
"id": "586c154d-1e0f-428c-97bc-200dec9328bb",
"d": "d",
"h": ["h", "i"],
"i": []
}
""")
println(validJson.validate[PQ])
val invalidJson = Json.parse("""
{
"id": "586c154d-1e0f-428c-97bc-200dec9328bb",
"d": "d",
"h": 123
}
""")
println(invalidJson.validate[PQ])
implicit val
s都提供相同的结果。
JsSuccess(PQ(586c154d-1e0f-428c-97bc-200dec9328bb,d,List(h, i),List()),)
JsError(List((/i,List(JsonValidationError(List(error.path.missing),WrappedArray()))), (/h,List(JsonValidationError(List(error.expected.jsarray),WrappedArray())))))
使用 play-json
我始终使用 case-classes
!
我将您的问题简化为本质:
import play.api.libs.json._
定义案例类
case class PQ(id:UUID, d:String, h:List[String], i: List[String])
在同伴object
中添加格式化器:
object PQ {
implicit val jsonFormat: Format[PQ] = Json.format[PQ]
}
并使用validate
:
Json.parse(YOUR_JSON).validate[PQ] match {
case JsSuccess(pq, _) => println(pq)
case JSError(errors) => println(s"Handle exception $other")
}
这将返回带有错误的PQ或列表。无需在这里做任何事情。