我有一个要求,即传入的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"
}
]
}
}
为了解析这个结构,我使用下面的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
)
将json转换为scala案例类对象的语句失败:
implicit val testReads = Json.reads[PersonUser]
错误说:
[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]
有人可以帮助我找出一种方法来表示Scala中的复杂json结构并使用Macro Inception或其他方式转换它吗?
答案 0 :(得分:4)
您需要为所有案例类创建Reads
,而不仅仅是顶层。例如:
case class Credential(handle:String, password:String,handle_type:String)
object Credential {
implicit val reads = Json.reads[Credential]
}
一旦你拥有了这些,Json.reads[PersonUser]
将能够工作。
答案 1 :(得分:1)
关于隐式读/写/格式的另一种方法可以是在单独的辅助对象中定义它们。必须按照特定顺序定义对象中的隐含,例如,隐式的顺序必须是: -
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
}
从上面的代码中可以了解到,必须首先定义嵌套层次结构底部的case classe的读取,然后是大写的类。
现在您只需要在服务中或在将JsValue转换为scala案例类的任何地方“导入JsonHelper._”。 :)