如何在Play 2.x中强制执行严格的JSON序列化

dcc*_*lie 5 json scala playframework-2.0

从JSON序列化为案例类时,Play的JSON序列化默认是允许的.例如.

case class Stuff(name: String, value: Option[Boolean])

implicit val stuffReads: Reads[Stuff] = (
  ( __ \ 'name).read[String] and
  ( __ \ 'value).readNullable[Boolean]
)(Stuff.apply _)
Run Code Online (Sandbox Code Playgroud)

如果收到以下JSON:

{name: "My Stuff", value: true, extraField: "this shouldn't be here"}
Run Code Online (Sandbox Code Playgroud)

它将通过'JsSuccess'成功并丢弃'extraField'.

有没有办法构造Json Reads函数,以便在存在"未处理"字段时返回JsError?

Tra*_*own 5

在执行自己的解码之前,您可以验证对象是否包含额外的键:

import play.api.data.validation.ValidationError

def onlyFields(allowed: String*): Reads[JsObject] = Reads.filter(
  ValidationError("One or more extra fields!")
)(_.keys.forall(allowed.contains))
Run Code Online (Sandbox Code Playgroud)

或者,如果您不关心错误消息(无论如何,这不是很有帮助):

def onlyFields(allowed: String*): Reads[JsObject] =
  Reads.verifying(_.keys.forall(allowed.contains))
Run Code Online (Sandbox Code Playgroud)

然后:

implicit val stuffReads: Reads[Stuff] = onlyFields("name", "value") andThen (
  (__ \ 'name).read[String] and
  (__ \ 'value).readNullable[Boolean]
)(Stuff)
Run Code Online (Sandbox Code Playgroud)

重复不是很好,但它的工作原理.