Scala序列化对象或任何对象

问题描述 投票:1回答:1

我遇到了序列化模型的问题:MyModel:

case class DocumentModel(
                          documentId: Option[Int] = None,
                          title: String,
                          ...
                          responsibleList: Option[Seq[UserModel]], // No problem
                          preConditions: Option[Seq[Object]], // Problem occurs here
                          postConditions: Option[Seq[Object]] // Problem occurs here
                        )

object DocumentModel {
  implicit val documentFormat = Jsonx.formatCaseClass[DocumentModel]
}

responsibleListpreConditions以及postConditions都没有存储在数据库中,它们只用作帮助列表。我继续在我的控制器中填写这些列表,以便通过JSON将其发送回前端:

val document = for {
  newDocument <- documentDTO.getDocument(documentId, clientId)
  responsibleList <- raciDocumentDTO.getResponsible_Documents(documentId)
  ...
  preConditions <- conditionController.getPreConditions(documentId)
  postConditions <- conditionController.getPostConditions(documentId)
} yield (newDocument, responsibleList, ..., preConditions, postConditions)

document.map({ case (newDocument, responsibleList, ..., preConditions, postConditions) =>
  val temp = newDocument.map(docu => {
    ...

    val doc = new DocumentModel(
      docu.documentId,
      docu.title,
      ...
      Some(responsibleList),
      Some(preConditions),
      Some(postConditions)
    )
    doc
  })

  Ok(Json.obj(
    "document" -> temp,
  ))
})

我怀疑它与Option[Seq[Object]]Option[Seq[Any]]有关。编译器抛出一个错误:enter image description here由于preConditionspostConditions可以是来自各种instances/objectsmodels,我无法明确说明它应该是哪个模型。有这个问题的解决方案还是我必须走另一条路?提前致谢!

UPDATE

我补充说:

trait Condition

object Condition {
  import play.api.libs.json._

  implicit val conditionWrites: Writes[Condition] = Writes[Condition] {
    case a: DocumentModel => JsObject(Seq("DocumentModel" -> Jsonx(a)))
    case b: ProcessModel => JsObject(Seq("ProcessModel" -> Jsonx(b)))
    case c: ProcessInstanceModel => JsObject(Seq("ProcessInstanceModel" -> Jsonx(c)))
  }
}

在我的模型中:

case class DocumentModel(
                          documentId: Option[Int] = None,
                          title: String,
                          ...,
                          responsibleList: Option[Seq[UserModel]],
                          preConditions: Option[Seq[Condition]],
                          postConditions: Option[Seq[Condition]]
                        ) extends Condition

它仍然留下这个错误消息:

enter image description here

enter image description here

这是我第一次遇到这样的问题,老实说我有点困惑。

更新2

我已经像你提到的那样尝试过,但它仍然会抛出相同的错误。

我的代码看起来像这样:

enter image description here

UPDATE

我实施了建议的更改,并将问题缩小到这个范围:

trait Condition

object Condition {
  implicit val conditionWrites: Writes[Condition] = Writes[Condition] {
    case a: DocumentModel => JsObject(Seq(
      "documentId" -> Json.toJson(a.documentId),
      "title" -> Json.toJson(a.title),
       ...
      "responsibleList" -> Json.toJson(a.responsibleList),
      "preConditions" -> Json.toJson(a.preConditions),
      "postConditions" -> Json.toJson(a.postConditions)
    ))
    case b: ...
  }

}

当我这样做时,我收到以下错误消息:

enter image description here所以我认为implicit read可能会丢失。所以我补充说:

object Condition {
  implicit val conditionReads: OFormat[Condition] = Json.format[Condition] // New

  implicit val conditionWrites: Writes[Condition] = Writes[Condition] {
    case a: DocumentModel => JsObject(Seq(
      "documentId" -> Json.toJson(a.documentId),
      "title" -> Json.toJson(a.title),
      ...

但是,在运行代码时,我得到了这个:

    No unapply or unapplySeq function found
    [error]   implicit val conditionReads: OFormat[Condition] = Json.format[Condition]

建议解决这个问题的方法是将我的object condition改为case class condition。但是,这会破坏创建这种通用trait/object的整个目的。

scala playframework playframework-2.0
1个回答
2
投票

让所有“条件”模型扩展具有JSON可写的特征。例如,

trait Condition

object Condition {

  implicit val conditionWrites: Writes[Condition] = Writes[Condition] {
    case a: PreConditionA => JsObject(Seq("field" -> JsString(a.stringValue))) //or whatever
    case b: PreConditionB => //...
    //etc...
    case x: PostConditionX => //...
    case y: PostConditionY => //...
    //etc...
  }

}

case class PreConditionA(stringValue: String) extends Condition
//etc.

然后在DocumentModel中,将条件的类型更改为Condition特征:

case class DocumentModel(
  documentId: Option[Int] = None,
  title: String,
  //...
  responsibleList: Option[Seq[UserModel]], 
  preConditions: Option[Seq[Condition]], 
  postConditions: Option[Seq[Condition]]
)

您可能必须将序列化语法转换为Jsonx的任何语法,但希望它足够相似并且您可以理解。

© www.soinside.com 2019 - 2024. All rights reserved.