爲了簡化事情我已經做了這樣的事情(儘管它創造了很多班):
假設:CONTACT_NAME是可選的,要摺疊整個事情到一個單一的情況下,類Contact
。
{
"contact_name": {
"first_name": "hello",
"last_name": "world"
},
"phone_number": "1231231234",
"email": "[email protected]"
}
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類並在模型中創建兩個case類:Contact
和ContactName
,但我想演示一個將View模型(Raw...
)與內部模型分開的通用解決方案。