使用Play2在Scala中进行json序列化时出错

时间:2015-07-17 10:06:56

标签: json scala playframework-2.3

我有以下三个案例类

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中的writeMessagemgslist中的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

请指导我如何摆脱它

也有更好的方法吗?

1 个答案:

答案 0 :(得分:0)

当您使用String构造JSON对象时,可以使用各种隐式转换将常见类型(例如IntJsString)转换为其JSON包装类型(JsNumberDelete)。您的代码存在的问题是,没有可用于将Message"delete" -> writeDelete(mgs.delete) 类型转换为JSON的隐式转换。一种选择是直接使用显式转换函数,例如:

Json.arr(...)

和(使用"msglist" -> Json.arr(inbox.getMessageList.toSeq.map(writeMessage): _*) 构造JSON数组):

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]
}

但是,更常用的方法是使用JSON Inception macros为您的类型自动生成(隐式)序列化程序。

稍微简化,这看起来像这样:

Delete

您现在应该可以使用Message自动序列化(和反序列化)InboxJson.toJson(thing)PUT个对象,因为它会找到隐式{ {3}}对象(合并FormatReads)在每个自定义类型的随播广告对象上。

此处的一个复杂因素是您的案例类包含枚举;如果他们是Scala枚举,请参阅Writes了解如何转换它们。我把它作为读者的练习。