Scala播放JSON自定义验证oneOf

时间:2019-02-28 22:22:43

标签: json scala validation playback

如何验证json,其中必须输入2个密钥之一。

Ex1:有效的Json

{
    "userName": "MyName",
    "userId": 123
}

Ex2:有效的Json

{
    "userName": "MyName"
}

Ex3:有效的Json

{
    "userId": 123
}

Ex4:无效的Json-缺少用户名和用户ID

{
    "email": "email@email.com"
}

我的案例课在下面

case class FindUser(userName: Option[String], userId: Option[Int]
object FindUser {
  implicit val findUserReads = Json.reads[FindUser]
}

控制器:

request.body.validate[FindUser]

1 个答案:

答案 0 :(得分:1)

作为解决方案之一,您可以实现自己的def reads(json: JsValue): JsResult[A]

import play.api.libs.json._

case class FindUser(userName: Option[String], userId: Option[Int])

object FindUser {
  implicit val findUserReads: Reads[FindUser] = new Reads[FindUser] {
    override def reads(json: JsValue): JsResult[FindUser] = {
      // Read and validate `userName` node
      val nameJsRes: JsResult[Option[String]] = (json \ "userName").validateOpt[String]
      // Read and validate `userId`
      val idJsRes: JsResult[Option[Int]] = (json \ "userId").validateOpt[Int]

      // For-comprehension which will fail fast
      // It will give JsError if:
      //  - nameJsRes is invalid
      //  - idJsRes is invalid
      //  - name and is are empty
      for {
        name <- nameJsRes
        id <- idJsRes
        result <- if (name.isEmpty && id.isEmpty) {
          JsError(JsonValidationError("Either `userName` or `userId` must be set"))
        }
        else {
          JsSuccess(FindUser(name, id))
        }
      } yield result
    }
  }

  def main(args: Array[String]): Unit = {
    // JsSuccess(FindUser(Some(123),Some(1123)),)
    println(Json.parse(
      """{
        |    "userName": "123",
        |    "userId": 1123
        |}""".stripMargin).validate[FindUser])

    // JsSuccess(FindUser(None,Some(1123)),)
    println(Json.parse(
      """{
        |    "userNameXXX": "123",
        |    "userId": 1123
        |}""".stripMargin).validate[FindUser])

    // JsSuccess(FindUser(Some(123),None),)
    println(Json.parse(
      """{
        |    "userName": "123",
        |    "userIdXXX": 1123
        |}""".stripMargin).validate[FindUser])

    // JsError(List((,List(JsonValidationError(List(Either `userName` or `userId` must be set),WrappedArray())))))
    println(Json.parse(
      """{
        |    "userNameXXX": "123",
        |    "userIdXXX": 1123
        |}""".stripMargin).validate[FindUser])
  }
}