自定义spray-json marshaller用于具有Value类型的案例类

时间:2016-03-07 09:43:55

标签: scala spray spray-json

case class HydraQueueMessage(tableType: HydraTableName.Value, payload: String)


object MedusaElementFormat extends DefaultJsonProtocol {
  implicit object HydraElementFormat extends RootJsonFormat[HydraQueueMessage] {
    def write(message: HydraQueueMessage) = JsObject(
      MedusaEnum.HydraTableName.toString -> JsString(message.tableType.toString),
      "payload" ->  JsString(message.payload)
    )
    def read(value: JsValue) = {
      value.asJsObject.getFields("tableType", "payload") match {
        case Seq(JsString(tableType), JsString(payload)) =>
          new HydraQueueMessage(tableType = tableType, payload = payload)
      }
    }
  }
}

在这个例子中有一种类型的错过匹配,是否有更简洁的方法来实现这一目标?并且仍然将tableType作为值而不是字符串?

我的marshaller使用Value类型抛出一个类型的miss-match,我也无法编组JsValue。那么如何在不使用HydraQueueMessage的字符串类型的情况下继续编组tableType案例类?

1 个答案:

答案 0 :(得分:3)

你正试图一次处理太多。我会把你的问题分成2:

  1. 处理HydraTableName.Value
  2. 处理HydraQueueMessage
  3. 这将使事情变得更容易。

    处理你的枚举:

    implicit object StepFormatJsonFormat extends RootJsonFormat[HydraTableName.Value] {
      def write(obj: HydraTableName.Value): JsValue = JsString(obj.toString)
    
      def read(jsonValue: JsValue): HydraTableName.Value = jsonValue match {
        case JsString(stringObj) => HydraTableName.withName(stringObj)
        case otherValue => throw new DeserializationException(s"HydraTableName.Value not found in ${otherValue.toString}")
      }
    }
    

    然后是典型的案例类格式:

    implicit val HydraQueueMessageFormat = jsonFormat2(HydraQueueMessage.apply)
    

    可能应该调整处理枚举的方法。 如果您包含HydraTableName,我可以更新代码。