使用 JSON 模式,如果您希望模式在有任何其他欄位的情況下驗證失敗,您可以只"additionalProperties": false在模式上拋出一個并像這樣呼叫它:
{
"$schema": "http://json-schema.org/draft-07/schema",
"type": "object",
"title": "",
"description": "",
"properties": {
"fieldOne": {
"type": "string",
"description": "Example String"
}
},
"additionalProperties": false
}
但是,如果我有以下案例類/物件:
case class MyThing(fieldOne: Option[String])
object MyThing {
implicit val reads: Reads[MyThing] = Json.reads[MyThing]
}
并提供它以外的東西fieldOne,它仍然會正確地將 JSON 作為案例類讀取,但案例類將為空。
當從 JSON 讀取到案例類時,在 JSON 中提供了額外的欄位時,有沒有辦法出錯?
uj5u.com熱心網友回復:
Play JSON 本身沒有這個,但在自定義中,Reads您可以從簡單的決議中訪問JsValue/ JsObject。因此,對于簡單的事情,您可以執行以下操作:
object MyThing {
// Single-abstract method should work, if not more explicitly extend Reads
implicit val reads: Reads[MyThing] = { json: JsValue =>
json match {
case JsObject(kv) =>
val keys = kv.keySet
if (keys != expectedFields) {
(keys -- expected).headOption.map { unexpected =>
JsError(s"Encountered unexpected field $unexpected")
}.getOrElse(JsError("Must be a non-empty object"))
} else derivedReads.reads(json)
case _ => JsError(JsonValidationError("must be an object"))
}
}
private val expectedFields = Set("fieldOne")
private val derivedReads = Json.reads[MyThing]
}
一般來說,假設您有一個符合Writes往返屬性的對應項,您可以執行以下操作:
def strictify[T](reads: Reads[T], writes: Writes[T]): Reads[T] = new Reads[T] {
def reads(json: JsValue): JsResult =
reads.reads(json).filter { t =>
val writeback = writes.writes(t)
writeback == json
}
}
這絕對比簽入 custom 效率低Reads,但它確實啟用
object MyThing {
implicit val writes: Writes[MyThing] = Json.writes[MyThing]
implicit val reads: Reads[MyThing] = strictify(Json.reads[MyThing], writes)
}
如果清晰度比性能更重要,這可能會贏。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/361518.html
