json - Play 2.3 隐式json转换导致空指针异常

标签 json scala playframework playframework-2.3

我正在尝试将 json 解析为我的案例类 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 和解析尝试
val str = """{"limit":10,"filter":{"date":"2014-10-27"}}"""
val frm = Json.parse(str).as[DealFormMap]

导致一个我似乎无法破解的神秘错误堆栈
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]

我在这里没有想法了,可能是什么问题?

最佳答案

问题是初始化顺序。 dealFormMapReads取决于隐式 dealFormFilterMapReads ,直到之后才定义。它会编译,因为找到了隐式,即使它没有被初始化,所以 dealFormMapReads读作 null ,最终导致 NPE。

延迟加载将修复它:

implicit val dealFormMapReads: Reads[DealFormMap] = (
     (JsPath \ "limit").readNullable[Int] and
     (JsPath \ "filter").lazyReadNullable[DealFormFilterMap](dealFormFilterMapReads)
)(DealFormMap)

或者你可以交换 Reads 的顺序被定义。

这里抛出的NPE类似于这个例子:
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`

关于json - Play 2.3 隐式json转换导致空指针异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26590918/

相关文章:

java - WSClient 和 SSL

json - 使用jq修改JSON

json - 如何在另一个 JObject 中循环动态 JObject?

json - 如何将所有拒绝内容转换为Spray中的自定义json?

Scala问题可选构造函数

playframework - Unresolved 依赖 : com. typesafe.play#play_2.10;2.2.1

android - 应为 BEGIN_ARRAY 但实际为 BEGIN_OBJECT

scala - 玩!框架使用异步 Web 请求组合操作

java - Scala 特征与 Java 8 接口(interface)之间有什么区别和相似之处?

playframework - Play 中 CRUD 表单和 Controller 的高级定制