【发布时间】:2014-11-24 14:44:37
【问题描述】:
我在 Play 中有一些模型!我想从 JSON 序列化/反序列化的应用程序。我曾经为此有单独的方法,但我发现首选方法是提供Formats[T] 或Reads[T] 的隐式实例,例如
import play.api.libs.json.{ JsValue, Reads }
case class Foo(bar: Int, ...)
object Foo {
implicit object FooReads extends Reads[Foo] {
def reads(json: JsValue): Foo = //whatever
}
}
现在,模型可能在 JSON 中有正确的字段,但它没有验证。在这种情况下,我无法反序列化 - 在使用 json.as[Foo] 或 None 时,我应该在使用 json.asOpt[Foo] 时遇到异常。
如果我在发现未验证的字段时抛出异常,则一切似乎都按预期工作。但我小心翼翼地试图找出我应该抛出什么异常,并在 JsValue 的源代码中找到了这个
def asOpt[T](implicit fjs: Reads[T]): Option[T] = fjs.reads(this).fold(
valid = v => Some(v),
invalid = _ => None
).filter {
case JsUndefined(_) => false
case _ => true
}
现在,我无法理解这应该如何工作。 fjs 的隐式实例是我自己在伴生对象中提供的,所以我知道 fjs.reads(this) 要么返回 Foo 要么抛出异常。
这个fold 来自哪里?这当然不是Foo 上的方法。我想可能会有一个隐式转换,但它应该是从 Any 到带有 fold 方法的东西,所以它不会引起太大的兴趣。更糟糕的是,如果fjs.reads(this) 抛出异常,则无法捕获它!
那么,在
Reads[T]的实例中,应该如何处理JSON 中的无效输入?上面的机制究竟是如何工作的?
【问题讨论】:
标签: json scala validation playframework playframework-json