Playframework JSON解析-空指针异常-存在数组时 [英] Playframework JSON parsing - Null pointer exception - when array is present

查看:83
本文介绍了Playframework JSON解析-空指针异常-存在数组时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用playframework进行JSON解析,并且遇到了以下NullPointerException:

I am using a playframework for JSON parsing and I am facing following NullPointerException:

我的数据模型如下:

case class SearchLikeThisResult(total: Int, max_score: Double, hits: Seq[Hits])
case class Hits( index: String, typ: String, id: String, score: Double)

我的读者如下:

object SearchLikeThisHits {

  import play.api.libs.functional.syntax._

  implicit val searchLikeThisResult: Reads[SearchLikeThisResult] = (
    (JsPath \ "total").read[Int] and
    (JsPath \ "max_score").read[Double] and
    (JsPath \ "hits").read[Seq[Hits]]
    )(SearchLikeThisResult.apply _)


  implicit val hitsReads: Reads[Hits] = (
    (JsPath \ "_index").read[String] and
      (JsPath \ "_type").read[String] and
      (JsPath \ "_id").read[String] and
      (JsPath \ "_score").read[Double]
    )(Hits.apply _)

}

然后我有以下测试代码:

Then I have following test code:

import play.api.libs.json.{JsValue, Json}

object Test extends App{

  val str = """{"total": 53, "max_score": 3.2948244, "hits": [
                                 {
                                     "_index": "hovno",
                                     "_type": "BYT",
                                     "_id": "3413569628",
                                     "_score": 3.2948244
                                 },
                                 {
                                      "_index": "hovno22",
                                      "_type": "BYT",
                                      "_id": "3413569628",
                                      "_score": 3.2948244
                                 }
                             ]
              }"""

  import SearchLikeThisHits.searchLikeThisResult

  val json = Json.parse(str)
  val r = json.as[SearchLikeThisResult]
}

这将导致以下NullPointerException:

This results in following NullPointerException:

Exception in thread "main" java.lang.NullPointerException
    at play.api.libs.json.Json$.fromJson(Json.scala:115)
    at play.api.libs.json.DefaultReads$$anon$2$$anonfun$reads$6.apply(Reads.scala:448)
    at play.api.libs.json.DefaultReads$$anon$2$$anonfun$reads$6.apply(Reads.scala:447)
    at scala.collection.LinearSeqOptimized$class.foldLeft(LinearSeqOptimized.scala:111)
    at scala.collection.immutable.List.foldLeft(List.scala:84)
    at scala.collection.generic.TraversableForwarder$class.foldLeft(TraversableForwarder.scala:41)
    at scala.collection.mutable.ListBuffer.foldLeft(ListBuffer.scala:45)
    at play.api.libs.json.DefaultReads$$anon$2.reads(Reads.scala:447)
    at play.api.libs.json.PathReads$$anonfun$at$1$$anonfun$apply$2.apply(JsConstraints.scala:36)
    at play.api.libs.json.PathReads$$anonfun$at$1$$anonfun$apply$2.apply(JsConstraints.scala:36)
    at play.api.libs.json.JsResult$class.flatMap(JsResult.scala:103)
    at play.api.libs.json.JsSuccess.flatMap(JsResult.scala:9)
    at play.api.libs.json.PathReads$$anonfun$at$1.apply(JsConstraints.scala:36)
    at play.api.libs.json.PathReads$$anonfun$at$1.apply(JsConstraints.scala:36)
    at play.api.libs.json.Reads$$anon$8.reads(Reads.scala:101)
    at play.api.libs.json.Reads$$anon$3$$anon$4.reads(Reads.scala:81)
    at play.api.libs.json.Reads$$anonfun$map$1.apply(Reads.scala:28)
    at play.api.libs.json.Reads$$anonfun$map$1.apply(Reads.scala:28)
    at play.api.libs.json.Reads$$anon$8.reads(Reads.scala:101)
    at play.api.libs.json.JsValue$class.as(JsValue.scala:65)
    at play.api.libs.json.JsObject.as(JsValue.scala:166)
    at models.data.Test$delayedInit$body.apply(Test.scala:33)
    at scala.Function0$class.apply$mcV$sp(Function0.scala:40)
    at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12)
    at scala.App$$anonfun$main$1.apply(App.scala:71)
    at scala.App$$anonfun$main$1.apply(App.scala:71)
    at scala.collection.immutable.List.foreach(List.scala:318)
    at scala.collection.generic.TraversableForwarder$class.foreach(TraversableForwarder.scala:32)
    at scala.App$class.main(App.scala:71)
    at models.data.Test$.main(Test.scala:9)
    at models.data.Test.main(Test.scala)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)

如果我删除一个所有工作的json数组.我从playframework json支持网页尝试了类似的示例,该示例正常工作.我在这里找不到问题. 我基于调试的猜测是,隐式可能存在问题,但不知道如何进一步帮助自己.我尝试使用"-Xprint:typer"编译器选项,但在那里没有发现任何可疑的东西.

If I remove an json array that all works. I tried similar example from playframework json support web pages which worked correctly. I can't spot the problem here. My guess based on debugging is that there might be an issue with implicits but dont know how to help myself more. I tried "-Xprint:typer" compiler option but haven't found anything suspicious there.

任何提示将不胜感激

推荐答案

这是初始化顺序问题.您需要先定义Reads[Hits] Reads[SearchLikeThisResult].之所以进行编译,是因为代码中存在该符号,而当初始化Reads[SearchLikeThisResult]时,Reads[Hits]则不存在.直到它尝试解析Hits的数组并命中NPE时,它才会被注意.

It's an initialization order problem. You need to define Reads[Hits] before Reads[SearchLikeThisResult]. It compiles because the symbol exists in the code, when when Reads[SearchLikeThisResult] is initialized, Reads[Hits] is not. It goes unnoticed until it attempts to parse the array of Hits, and hits the NPE.

因此,只需交换订单即可.这与此答案有关.

So just swap the order. This is related to this answer.

implicit val hitsReads: Reads[Hits] = (
    (JsPath \ "_index").read[String] and
    (JsPath \ "_type").read[String] and
    (JsPath \ "_id").read[String] and
    (JsPath \ "_score").read[Double]
)(Hits.apply _)

implicit val searchLikeThisResult: Reads[SearchLikeThisResult] = (
    (JsPath \ "total").read[Int] and
    (JsPath \ "max_score").read[Double] and
    (JsPath \ "hits").read[Seq[Hits]]
)(SearchLikeThisResult.apply _)

这篇关于Playframework JSON解析-空指针异常-存在数组时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆