简体   繁体   English

无法使用JSON Macro Inception将嵌套的JSON结构转换为Scala case类对象

[英]Not able to use JSON Macro Inception to convert nested JSON structure to Scala case class object

I have a requirement where the incoming JSON object is complex and mostly nested ex: 我有一个要求,其中传入的JSON对象很复杂,并且大多是嵌套的:

"users": {
  "utype": "PERSON",
  "language":"en_FR",
  "credentials": [
    {          
      "handle": "xyz@abc.com",
      "password": "123456",
      "handle_type": "EMAIL"
    }
  ],
  "person_details": {
    "primary": "true",
    "names": [
      {
      "name_type": "OFFICIAL",
      "title": "MR",
      "given": "abc",
      "family": "zat",
      "middle": "pqs",
      "suffix":"anathan"
     }
    ],
    "addresses": [
      {
        "ad_type": "HOME",
        "line1": "Residential 2211 North 1st Street",
        "line2": "Bldg 17",
        "city": "test",
        "county": "Shefield",
        "state" : "NY",
        "country_code": "xx",
        "postal_code": "95131"
      }
    ]
  }
}

For parsing this structure I use the below Case Classes 为了解析此结构,我使用以下案例类

case class PersonUser (
    user_type:String,
    language_code:String,
    credentials:List[Credential],
    person_details:PersonDetails
)

case class Credential(handle:String, password:String,handle_type:String)

case class PersonDetails(
    primary_user:Boolean,
    names: List[Name],
    addresses:List[Address]
)

case class Name(
    name_type: String,
    title: String,
    given: String,
    family: String,
    middle: String,
    suffix:String
)

case class Address(
    address_type: String,
    line1: String,
    line2: String,
    city: String,
    county: String,
    state : String,
    country_code: String,
    postal_code: String
)

The statement to convert the json to scala case class object is failing: 将json转换为scala case类对象的语句失败:

implicit val testReads = Json.reads[PersonUser]

The errors says: 错误说:

[scala-play-rest-example] $ compile
[info] Compiling 4 Scala sources to C:\Personal\Scala\scala-play-rest-example-master\target\scala-2.11\classes...
[error] C:\Personal\Scala\scala-play-rest-example-master\app\controllers\user\UserController.scala:16: **No implicit Reads for List[controllers.user.Credential], controllers.user.PersonDetails available.**
[error]     implicit val testReads = Json.reads[PersonUser]

Can someone please help me out to find out a way to represent complex json structure in Scala and convert it using Macro Inception or some other ways? 有人可以帮我找出一种在Scala中表示复杂json结构并使用Macro Inception或其他方法进行转换的方法吗?

You need to create Reads for all of your case classes, not just the top-level. 您需要为所有案例类(而不只是顶层)创建Reads For instance: 例如:

case class Credential(handle:String, password:String,handle_type:String)

object Credential {

  implicit val reads = Json.reads[Credential]

}

Once you have those, Json.reads[PersonUser] will be able to work. 一旦有了这些, Json.reads[PersonUser]就可以工作。

One other approach regarding the implicit reads/writes/format can be to define them in a separate helper object. 关于隐式读/写/格式的另一种方法可以是在单独的帮助程序对象中定义它们。 Implicit in the object must be defined in a specific order like in your case the order of the implicit must be :- 必须按照特定的顺序定义对象中的隐式,例如在您的情况下,隐式的顺序必须为:-

object JsonHelper {
  implicit val nameReads = Json.reads[Name]
  implicit val addressReads = Json.reads[Address]  //position of 'nameReads' and 'addressReads' is interchangable
  implicit val credentialReads = Json.reads[Credential]
  implicit val personReads = Json.reads[PersonDetails]  // similarly position of 'credentialReads' and 'personReads' is interchangable
  implicit val personUserReads = Json.reads[PersonUser]  //'personUserReads' will always be the last
}

From the above code it can be learnt that the reads of case classe at the bottom of nesting hierarchy must be defined first, followed by the top case classes. 从上面的代码可以知道,必须首先定义嵌套层次结构底部的案例类读取,然后再定义顶级案例类。

Now you just need to 'import JsonHelper._' in your service or wherever you are converting your JsValue to scala case class. 现在,您只需要在服务中或将JsValue转换为scala case类的任何位置“导入JsonHelper._”。 :) :)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM