为了简化事情,我做了这样的事情(尽管它确实创建了很多类):
假设:contact_name 是可选的,并且您希望将整个内容折叠成单个案例类Contact。
{
"contact_name": {
"first_name": "hello",
"last_name": "world"
},
"phone_number": "1231231234",
"email": "test@gmail.com"
}
case class Contact(firstName: Optional[String], lastName: Optional[String], phoneNumber: String, email: String)
case class RawContactName(firstName: String, lastName: String)
case class RawContact(contactName: Optional[RawContactName], phoneNumber: String, email: String)
implicit val rawContactReads: Reads[RawContact] = (
(JsPath \ "contact_name").readNullable[RawContactName] and
(JsPath \ "phone_number").read[String] and
(JsPath \ "email").read[String]
) (RawContact.apply _)
implicit val rawContactNameReads: Reads[RawContactName] = (
(JsPath \ "first_name").read[String] and
(JsPath \ "last_name").read[String]
) (RawContactName.apply _)
def transformContact(rawContact: RawContact): Contact = {
val (maybeFirstName, maybeLastName) = rawContact.contactName match {
case Some(RawContactName(firstName, lastName)) => (Some(firstName), Some(lastName))
case None => (None, None)
}
Contact(maybeFirstName, maybeLastName, rawContact.phoneNumber, rawContact.email)
}
实际上,我有单独的案例类来表示每个 JSON 节点和一个转换器函数来将 Scala JSON 表示转换为我的模型类。如果您有重复的值(例如:同一个 JSON 文档中有多个联系人对象,因此会出现多个 first_name 元素),这将很有效。尽管在您的具体示例中,最好跳过 Raw 类并在模型中创建两个案例类:Contact 和 ContactName 但我想演示一个将 View 模型(Raw...)与内部模型。