使用play framework和scala检查或查找json中是否存在特定路径

使用play framework和scala检查或查找json中是否存在特定路径,json,scala,playframework,Json,Scala,Playframework,我正在尝试使用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 Ap

我正在尝试使用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-account-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]])
}
在第二个对象的resources数组中,您可以看到此代码完全丢失

"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")
特定路径存在,然后仅读取该路径中的元素。 或者我应该编写一个自定义函数来检查路径是否存在

我可以看到一个JsDefined()需要一个Jsvalue


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

可能会有帮助

第一种方法是使用Json。格式:

import play.api.libs.json_
对象解析JSON扩展应用程序{
案例类Msisdn(`primaryid`:Option[String],meta:Option[meta])
案例类元(`related account id`:Option[String])
隐式val metaFormat=Json.format[Meta]
隐式val msisdnFormat=Json.format[Msisdn]
输出:
List(Msisdn(一些(393823468484),一些(Meta(一些(10001771))),Msisdn(一些(393823467689),无))

然后你可以用

case类Msisdn(private val`primary id`:Option[String],
私有值元:选项[meta]){
def primaryId:选项[字符串]=`主id`
def accountId:Option[String]=meta.flatMap(551; `相关帐户id`)
}
更改公共API

第二种方法是使用。但我认为你可以小心使用

case类Msisdn(primaryId:Option[String],relatedcountid:Option[String])
对象Msisdn{
隐式val readData:读取[Msisdn]=(
(JsPath \“主id”).readNullable[字符串]~
(JsPath\\“相关帐户id”).readNullable[字符串]
)(Msisdn.apply)
}
3-rd是使用
新格式
。在这种情况下,您可以使用json对象,并检查字段是否存在

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


对不起,我的英语太差了。

可能会有帮助

第一种方法是使用Json。格式

import play.api.libs.json_
对象解析JSON扩展应用程序{
案例类Msisdn(`primaryid`:Option[String],meta:Option[meta])
案例类元(`related account id`:Option[String])
隐式val metaFormat=Json.format[Meta]
隐式val msisdnFormat=Json.format[Msisdn]
输出:
List(Msisdn(一些(393823468484),一些(Meta(一些(10001771))),Msisdn(一些(393823467689),无))

然后你可以用

case类Msisdn(private val`primary id`:Option[String],
私有值元:选项[meta]){
def primaryId:选项[字符串]=`主id`
def accountId:Option[String]=meta.flatMap(551; `相关帐户id`)
}
更改公共API

第二种方法是使用。但我认为你可以小心使用

case类Msisdn(primaryId:Option[String],relatedcountid:Option[String])
对象Msisdn{
隐式val readData:读取[Msisdn]=(
(JsPath \“主id”).readNullable[字符串]~
(JsPath\\“相关帐户id”).readNullable[字符串]
)(Msisdn.apply)
}
3-rd是使用
新格式
。在这种情况下,您可以使用json对象,并检查字段是否存在

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

对不起,我的英语不好。

没有,但是按规则玩会更容易

import play.api.libs.json_
案例类MsisdnMeta(relatedAccountId:选项[字符串])
对象MsisdnMeta{
私有隐式val jsonConfiguration:jsonConfiguration=
JsonConfiguration(JsonNaming{{{u=>“相关帐户id”})
隐式val格式:OFormat[MsisdnMeta]=Json.format
}
案例类Msisdn(
primaryId:选项[字符串],
元:选项[MsisdnMeta]){
@内联def relatedAccountId:选项[字符串]=
meta.flatMap(u.relatedAccountId)
}
对象Msisdn{
私有隐式val jsonConfiguration:jsonConfiguration=
JsonConfiguration(JSONNameing{
案例“primaryId”=>“primaryId”
案例=>“元”
})
隐式val格式:OFormat[Msisdn]=Json.format
}
然后读取/解析JSON:

val json=json.parse(“”){
“开始日期时间有效”:“2019-08-23T10:47:17.485Z”,
“主id”:“393823468484”,
“元”:{
“相关账户id”:“10001771”,
“角色”:[
“客户”
]
}
}""")
val res=json.validate[Msisdn]
//play.api.libs.json.JsResult[Msisdn]=JsSuccess(Msisdn(一些(3938234684),一些(MsisdnMeta(一些(10001771))),)
res.foreach{suc=>
println(s“relatedAccountId=${suc.relatedAccountId}”)
}
//relatedAccountId=Some(10001771)
…并写入JSON:

Json.toJson(Msisdn(一些(“id”),一些(MsisdnMeta(一些(“bar”)))))
//play.api.libs.json.JsValue={“主id”:“id”,“meta”:{“相关帐户id”:“bar”}
通过向伴生对象添加一些工厂,可以更轻松地创建带有嵌套元的
Msisdn

对象Msisdn{
//附加工厂
@内联def应用(
primaryId:选项[字符串],
relatedAccountId:字符串):Msisdn=
Msisdn(primaryId,Some(MsisdnMeta(Some(relatedcountid)))
私有隐式val jsonConfiguration:jsonConfiguration=
JsonConfiguration(JSONNameing{
案例“primaryId”=>“primaryId”
案例=>“元”
})
隐式val格式:OFormat[Msisdn]=Json.format
}
toJson(Msisdn(一些(“id”),“bar”))
//play.api.libs.json.JsValue={“主id”:“id”,“meta”:{“相关帐户id”:“bar”}
没有可用的,但按规则玩会更容易

import play.api.libs.json_
案例类MsisdnMeta(relatedAccountId:Option[St
final case classJsDefined(value: JsValue)
Wrapper for JsValue to represent an existing Json value.