用于 Play 的 Json "Validate"

标签 json scala validation playframework playframework-2.0

对于 request.body 上的 validate 方法,它将 json 对象的属性名称和值类型与模型定义中定义的匹配。现在,如果我要向 json 对象添加一个额外的属性并尝试验证它,它会在不应该的时候作为 JsSuccess 传递。

{ 
    "Name": "Bob",
    "Age": 20,
    "Random_Field_Not_Defined_in_Models": "Test"
}

我的 Person 类定义如下
case class Person(name: String, age: Int)

最佳答案

我假设你一直在使用内置的 Reads[T]Format[T] Play 通过 Json.reads[T] 为您提供的转换器,例如:

import play.api.libs.json._

val standardReads = Json.reads[Person]

虽然这些非常方便,但如果您需要 附加 验证,您必须定义一个自定义 Reads[Person]类(class);但幸运的是,我们仍然可以利用内置的 JSON-to-case-class 宏来进行基本的检查和转换,然后在一切正常的情况下添加额外的自定义检查层:
val standardReads = Json.reads[Person]

val strictReads = new Reads[Person] {
  val expectedKeys = Set("name", "age")

  def reads(jsv:JsValue):JsResult[Person] = {
    standardReads.reads(jsv).flatMap { person =>
      checkUnwantedKeys(jsv, person)
    }
  }

  private def checkUnwantedKeys(jsv:JsValue, p:Person):JsResult[Person] = {
    val obj = jsv.asInstanceOf[JsObject]
    val keys = obj.keys
    val unwanted = keys.diff(expectedKeys)
    if (unwanted.isEmpty) {
      JsSuccess(p)
    } else {
      JsError(s"Keys: ${unwanted.mkString(",")} found in the incoming JSON")
    }
  } 
} 

注意我们如何使用 standardReads 首先,确保我们正在处理可以转换为 Person 的内容。 .无需在这里重新发明轮子。

我们使用 flatMap如果我们得到 JsError,则有效地短路转换来自 standardReads - 即我们只调用 checkUnwantedKeys如果需要的话。

checkUnwantedKeys 只是使用 JsObject 的事实是 really just a wrapper around a Map ,因此我们可以轻松地根据白名单检查 key 的名称。

备注 你也可以写成 flatMap使用 for-comprehension,如果您需要更多检查阶段,它开始看起来更干净:
for {
    p <- standardReads.reads(jsv)
    r1 <- checkUnexpectedFields(jsv, p)
    r2 <- checkSomeOtherStuff(jsv, r1)
    r3 <- checkEvenMoreStuff(jsv, r2)
} yield r3

关于用于 Play 的 Json "Validate",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36136346/

相关文章:

ios - Cocoa - 在 NSDictionary 中引用一个 KEY

javascript - Angular 2 : How to display image to HTML from JSON API

java - `java.nio.file.Files.createFile` 是阻塞调用吗?

regex - 斯卡拉玩 : Invalid '@' symbol in email regex

c# - 验证我的钱

mysql - JSON_EXTRACT 和方括号

scala - Scala 2.10.1 中未找到隐式宏?

Django - ModelChoiceField 查询集是如何工作的?

php - 如何在 php 中使用 preg_match?

json - 解析嵌套在表单 urlencoded POST 中的 JSON 字符串