2015-07-17 5 views
0

я имею следующие три тематических классыОшибка в JSon сериализации в Scala с PLAY2

case class Delete(var deleteStatus : DeleteStatus , var deleteReason : DeleteReason) // DeleteStatus and DeleteReason are enums 

case class Message(val uuid: Int ,val subject : String, val body : String, var awt : Int,val dateTime : LocalDateTime = LocalDateTime.now(), delete : Delete) 

case class Inbox(val uuid : Int,var messageList : ListBuffer[Message]) 

я хочу сериализацию их Json и, но я не уверен, как я должен это сделать

я пробовал как это

def writedelete(delete: Delete) = Json.obj(
     "deleteStatus" -> delete.getDeleteStatusInt.toString, 
     "deleteReason" -> delete.getDeleteReasonInt.toString 
    ) 

     def writeMessage(mgs : Message)= Json.obj(
     "uuid" -> mgs.getUuid , 
     "subject" -> mgs.getSubject, 
     "body" -> mgs.getBody, 
     "awt" -> mgs.getAwt, 
     "datetime" -> mgs.getdateTime.toString, 
     "delete" -> mgs.delete 
    ) 



    def writeInbox(inbox : Inbox)= Json.obj(
     "uuid" -> inbox.getUuid, 
     "mgslist" -> Seq(inbox.getMessageList) 
    ) 

, но он дает следующее сообщение об ошибке на mgs.delete в writeMessage и mgslist в writeInbox

type mismatch; found : models.UserNotifications.MailMessages.Delete 
required: play.api.libs.json.Json.JsValueWrapper 

type mismatch; found : 
Seq[scala.collection.mutable.ListBuffer[models.UserNotifications.MailMessages.Message]] 
required: play.api.libs.json.Json.JsValueWrapper 

, пожалуйста, руководство меня, как я могу получить избавиться от него

, а также есть ли лучший способ сделать это?

ответ

0

При использовании Json.obj(...) построить JSON объект различные неявные преобразования доступны для преобразования распространенных типов (например, String, Int) с их типами оболочек JSON (JsString, JsNumber). Проблема с вашим кодом заключается в том, что нет никаких неявных преобразований, доступных для преобразования типов Delete и Message в JSON. Одним из вариантов было бы использовать свои явные функции преобразования непосредственно, например:

"delete" -> writeDelete(mgs.delete) 

и (используя Json.arr(...) построить массив JSON):

"msglist" -> Json.arr(inbox.getMessageList.toSeq.map(writeMessage): _*) 

Однако более идиоматических способ сделать это должно было бы использовать JSON Inception macros для автоматического создания (неявных) сериализаторов для ваших типов.

Упрощая немного, это будет выглядеть примерно так:

case class Delete(deleteStatus: DeleteStatus, deleteReason: DeleteReason) 
object Delete { 
    implicit val _format = Json.format[Delete] 
} 

case class Message(uuid: Int, subject: String, body: String, awt: Int, dateTime: LocalDateTime, delete: Delete) 
object Message { 
    implicit val _format = Json.format[Message] 
} 

case class Inbox(uuid: Int, messageList: ListBuffer[Message]) 
object Inbox { 
    implicit val _format = Json.format[Message] 
} 

Вы должны теперь быть в состоянии автоматически сериализовать (и десериализации) ваш Delete, Message и Inbox объектов с помощью Json.toJson(thing), потому что он найдет неявный объект Format (объединенный Reads и Writes) на сопутствующем объекте каждого настраиваемого типа.

Одно осложнение здесь заключается в том, что классы case содержат перечисления; если они перечислены Scala, см. this answer о том, как их преобразовать. Я оставляю это как упражнение для читателя.