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

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

本文介绍了Play 2.3 隐式json转换导致空指针异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将 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转换导致空指针异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-22 20:23