问题描述
我正在尝试将 json 解析为我的案例类 DealFormMap
I'm trying to parse json into my case class DealFormMap
case class DealFormMap(limit: Option[Int], filter: Option[DealFormFilterMap])
case class DealFormFilterMap(date: Option[String], code: Option[String])
implicit val dealFormMapReads: Reads[DealFormMap] = (
(JsPath "limit").readNullable[Int] and
(JsPath "filter").readNullable[DealFormFilterMap]
)(DealFormMap)
implicit val dealFormFilterMapReads: Reads[DealFormFilterMap] = (
(JsPath "date").readNullable[String] and
(JsPath "code").readNullable[String]
)(DealFormFilterMap)
有问题的 JSON 和解析尝试
JSON in question and parsing attempt
val str = """{"limit":10,"filter":{"date":"2014-10-27"}}"""
val frm = Json.parse(str).as[DealFormMap]
导致一个我似乎无法破解的神秘错误堆栈
causes a cryptic error stack that I just can't seem to crack
play.api.Application$$anon$1: Execution exception[[NullPointerException: null]]
at play.api.Application$class.handleError(Application.scala:296) ~[play_2.11-2.3.5.jar:2.3.5]
at play.api.DefaultApplication.handleError(Application.scala:402) [play_2.11-2.3.5.jar:2.3.5]
at play.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$14$$anonfun$apply$1.applyOrElse(PlayDefaultUpstreamHandler.scala:205) [play_2.11-2.3.5.jar:2.3.5]
at play.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$14$$anonfun$apply$1.applyOrElse(PlayDefaultUpstreamHandler.scala:202) [play_2.11-2.3.5.jar:2.3.5]
at scala.runtime.AbstractPartialFunction.apply(AbstractPartialFunction.scala:36) [scala-library-2.11.2.jar:na]
Caused by: java.lang.NullPointerException: null
at play.api.libs.json.PathReads$$anonfun$nullable$1$$anonfun$apply$7$$anonfun$apply$9.apply(JsConstraints.scala:65) ~[play-json_2.11-2.3.5.jar:2.3.5]
at play.api.libs.json.PathReads$$anonfun$nullable$1$$anonfun$apply$7$$anonfun$apply$9.apply(JsConstraints.scala:63) ~[play-json_2.11-2.3.5.jar:2.3.5]
at play.api.libs.json.JsResult$class.fold(JsResult.scala:76) ~[play-json_2.11-2.3.5.jar:2.3.5]
at play.api.libs.json.JsSuccess.fold(JsResult.scala:9) ~[play-json_2.11-2.3.5.jar:2.3.5]
at play.api.libs.json.PathReads$$anonfun$nullable$1$$anonfun$apply$7.apply(JsConstraints.scala:61) ~[play-json_2.11-2.3.5.jar:2.3.5]
我的想法不多了,可能是什么问题?
I'm running out of ideas here, what could be the problem?
推荐答案
问题是初始化顺序.dealFormMapReads
依赖于隐式的 dealFormFilterMapReads
,直到之后才定义.它会编译,因为找到了隐式,即使它没有被初始化,所以 dealFormMapReads
被读取为 null
,最终导致 NPE.
The problem is the initialization order. dealFormMapReads
depends on the implicit dealFormFilterMapReads
, which isn't defined until after. It will compile because the implicit is found, even though it hasn't been initialized, so dealFormMapReads
is read as null
, which eventually causes the NPE.
延迟加载将修复它:
implicit val dealFormMapReads: Reads[DealFormMap] = (
(JsPath "limit").readNullable[Int] and
(JsPath "filter").lazyReadNullable[DealFormFilterMap](dealFormFilterMapReads)
)(DealFormMap)
或者您可以交换定义 Reads
的顺序.
Or you could just swap the order in which the Reads
are defined.
这里抛出的NPE类似于这个例子:
The NPE thrown here is similar to this example:
case class A(i: Int)
object Test {
val test = a.toString
val a = A(1)
}
// Compiles up to here
Test.test // throws NPE, because `a` was not initialized before `test`
这篇关于Play 2.3 隐式json转换导致空指针异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!