我在 Play 中有一些模型!我想从 JSON 序列化/反序列化的应用程序。我曾经有单独的方法,但我已经看到首选的方法是给出Formats[T]
or的隐式实例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)
要么返回 aFoo
要么抛出异常。
这是fold
从哪里来的?它当然不是一种方法Foo
。我想一个人可能有一个隐式转换,但它应该是从Any
某种fold
方法到某物,所以它不会引起太大兴趣。更糟糕的是,如果fjs.reads(this)
抛出异常,则没有任何东西可以捕获它!
那么,应该如何处理 JSON 中的无效输入
Reads[T]
?上面的机制实际上是如何工作的?