使用播放框架和Scala检查或查找json中是否存在特定路径

问题描述 投票:0回答:1

我正在尝试使用play框架将json解析为case类。我的目的是检查json中是否存在特定路径。如果存在,则仅读取该路径上的元素。

这是我的代码

package com.learning.avinash.query

import play.api.libs.json.{JsDefined, JsPath, Json, Reads, Writes, __}
import play.api.libs.functional.syntax._

object ParseJson extends App {

  case class Msisdn(primaryId: Option[String], relatedAccountId: Option[String])

  object Msisdn {
    implicit val readData: Reads[Msisdn] = (
      (JsPath \ "primary-id").readNullable[String] ~
      (JsPath \ "meta" \ "related-accoount-id").readNullable[String]
      ) (Msisdn.apply _)
  }



val testJson = """{
  "resources": [
    {
    "valid-for-start-datetime": "2019-08-23T10:47:17.485Z",
    "primary-id": "393823468684",
      "meta": {
        "related-account-id": "10001771",
            "roles": [
              "customer"
            ]
        }
    },
  {
    "valid-for-start-datetime": "2019-08-23T10:47:17.485Z",
    "primary-id": "393823467689"
    }
  ]
}"""
    println((Json.parse(testJson) \ "resources").as[List[Msisdn]])
}

在第二个对象的资源数组中,您可以观察到此代码完全丢失

"meta": {
            "related-account-id": "10001771",
                "roles": [
                  "customer"
                ]
            }

现在,当我尝试解析json时,它失败并且出现以下异常

Exception in thread "main" play.api.libs.json.JsResultException: JsResultException(errors:List(((1)/meta/related-accoount-id,List(JsonValidationError(List(error.path.missing),WrappedArray())))))

正在播放中是否有预定义的功能/方法,以便我可以检查是否此

(JsPath \ "meta")

特定路径存在,然后仅读取该路径中的元素。还是应该编写一个自定义函数来检查路径是否存在。

我可以看到一个期望有Jsvalue的JsDefined()。

https://www.playframework.com/documentation/2.7.x/api/scala/play/api/libs/json/index.html

final case classJsDefined(value: JsValue)
Wrapper for JsValue to represent an existing Json value.

请提供任何想法,想法,帮助或建议。

json scala playframework
1个回答
0
投票

也许会有所帮助...

import play.api.libs.json._

object ParseJson extends App {

  case class Msisdn(`primary-id`: Option[String], meta: Option[Meta])
  case class Meta(`related-account-id`: Option[String])
  implicit val metaFormat = Json.format[Meta]
  implicit val msisdnFormat = Json.format[Msisdn]

输出:List(Msisdn(Some(393823468684),Some(Meta(Some(10001771)))), Msisdn(Some(393823467689),None))

然后您可以使用

case class Msisdn(private val `primary-id`: Option[String],
                  private val meta: Option[Meta]) {
  def primaryId: Option[String] = `primary-id`
  def accountId: Option[String] = meta.flatMap(_.`related-account-id`)
}

更改公共API。

还有另一种方法,但是我忘了怎么做。

© www.soinside.com 2019 - 2024. All rights reserved.