播放Json - 反序列化模型时发生冲突

时间:2017-04-06 10:55:13

标签: json scala playframework-2.0

我在单元测试中遇到了一个奇怪的问题,关于JSON中的case类的序列化/反序列化。我正在使用play-json (2.5.10),我为我的活动定义了一个模型:

case class BFFEvent
  (
    startTime: Long,
    endTime: Long,
    eventType: BFFEventType.Value, // just an enum 
    payload: Option[Payload]
  )

  object BFFEvent {
    implicit val BFFEventFormat = Json.format[BFFEvent]
  }

Payload是一个包含许多子类型的ADT,但我只提出了冲突的案例类:

sealed trait Payload

case class UserFlag
  (
    flag: Option[BFFEventFlag],
    freeText: Option[String],
    source: Option[BFFEventSource],
    timestamp : Option[Timestamp]
  ) extends Payload

case class CommunicationMode(mode: Int) extends Payload


implicit val payloadReads = {
    val userFlag = Json.reads[UserFlag]
    val communicationMode = Json.reads[CommunicationMode]

      __.read[UserFlag](userFlag).map(x => x: Payload) |
      __.read[CommunicationMode](communicationMode).map(x => x: Payload)

  }

  implicit val payloadWrites = Writes[Payload] {
    case userFlag: UserFlag => Json.writes[UserFlag].writes(userFlag)
    case communicationMode: CommunicationMode => Json.writes[CommunicationMode].writes(communicationMode)
  }

在单元测试中,我检查是否可以读/写我的有效载荷模型的JSON:

val communicationMode = BFFEvent(0, 0, BFFEventType.COMMUNICATIONMODE, Some(CommunicationMode(0)))

it should "serialize and deserialize a CommunicationMode" in {
    val validatedJSON = Json.toJson(communicationMode).validate[BFFEvent]
    validatedJSON should be(JsSuccess(communicationMode))
  }

测试输出:

BFFEvent(0,0,COMMUNICATIONMODE,Some(CommunicationMode(0)))
JsSuccess(BFFEvent(0,0,COMMUNICATIONMODE,Some(UserFlag(None,None,None,None))),)

JsSuccess(BFFEvent(0,0,COMMUNICATIONMODE,Some(UserFlag(None,None,None,None))),) was not equal to JsSuccess(BFFEvent(0,0,COMMUNICATIONMODE,Some(CommunicationMode(0))),)
ScalaTestFailureLocation: com.bioserenity.bff.test.TEST_BFF_MODELS_SERIALIAZER$$anonfun$1 at (TEST_BFF_MODELS_SERIALIAZER.scala:81)
Expected :JsSuccess(BFFEvent(0,0,COMMUNICATIONMODE,Some(CommunicationMode(0))),)
Actual   :JsSuccess(BFFEvent(0,0,COMMUNICATIONMODE,Some(UserFlag(None,None,None,None))),)

虽然json转换的输入是带有BFFEvent有效负载的CommunicationMode,但它转换为UserFlag。我认为问题来自于payloadReads函数中的匹配顺序,但改变匹配案例的顺序会产生另一种混淆,所以如果有人以前遇到过这个问题,他能否给我一个解决它或更好的解决方案,一个解决方案?

0 个答案:

没有答案