【问题标题】:scala play json custom validation oneOfscala play json 自定义验证 oneOf
【发布时间】:2019-02-28 22:22:43
【问题描述】:

如何验证 json where-in 两个键之一是强制性的。

Ex1:有效的 Json

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

Ex2:有效的 Json

{
    "userName": "MyName"
}

Ex3:有效的 Json

{
    "userId": 123
}

Ex4:无效的 Json - 缺少 UserName 和 userId

{
    "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]

【问题讨论】:

  • 使用哪个 JSON 库?
  • 我正在使用 play-json 库

标签: json scala validation playback


【解决方案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])
  }
}

【讨论】:

  • 谢谢。这对我有用。我可以摆脱我正在编写的其他自定义代码来做同样的事情。
猜你喜欢
  • 2014-12-06
  • 2012-06-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多