为具有值类型的案例 class 自定义 spray-json 编组器

custom spray-json marshaller for a case class with Value type

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 作为值而不是字符串?

我的编组器抛出与 Value 类型的类型不匹配,我也无法编组 JsValue。那么我如何在不为 tableType 使用 String 类型的情况下继续编组 HydraQueueMessage 案例 class?

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

  1. 进程HydraTableName.Value
  2. 进程HydraQueueMessage

这会让事情变得容易得多。

要处理您的枚举:

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}")
  }
}

然后典型案例class格式化:

implicit val HydraQueueMessageFormat = jsonFormat2(HydraQueueMessage.apply)

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