Scala Play Framework 2.6 密封特征格式为 Json

Scala Play Framework 2.6 sealed trait format to Json

我希望能够从伴随对象读取和写入 Json 格式。在 class 的情况下,我将类型 currency 定义为密封特征 Currency 以便能够限制它可以是的值。

我有这个案例 class 及其伴生对象

case class Payment(
  id: Long,
  amount: BigDecimal,
  currency: Currency
)

object Payment {
  implicit val paymentFormat = Json.format[Payment]
  val tupled = (this.apply _).tupled
}

和这个密封的特性

sealed trait Currency { def name: String }
case object EUR extends Currency { val name = "eur" }
case object USD extends Currency { val name = "usd" }
case class UnknownCurrency(name: String) extends Currency

我希望能够将对象转换为 json 做 Json.toJson(payment) 或阅读 json。但是我不能,因为我在 paymentFormat 中有一些错误。我试过这个

object Currency {
  implicit object CurrencyFormat extends Format[Currency] {
    implicit def reads(json: JsValue) =
      json match {
        case JsString("eur") => JsSuccess(EUR)
        case JsString("usd") => JsSuccess(USD)
        case _ => JsError("cannot parse it")
      }
    implicit def writes(currency: Currency) = JsString(currency.name.toString)
  }
}

当我尝试编译项目时出现此错误

No instance of Reads is available for models.entities.EUR in the implicit scope

改为这样做:

object Currency {

  implicit val reads: Reads[Currency] = Reads {
    case JsString("eur") => JsSuccess(EUR)
    case JsString("usd") => JsSuccess(USD)
    case _ => JsError("cannot parse it")
  }

  implicit val writes: Writes[Currency] = Writes { currency =>
    JsString(currency.name.toString)
  }

}

由于我们最终在问题评论中解决了您的问题,因此我 post 在此处将修复评论作为答案:

出现以下错误:

No instance of Reads is available for models.entities.EUR in the implicit scope

已通过正确导入 Format 实例修复。例如:

implicit lazy val currencyFormat: Format[Currency] = Currency.CurrencyFormat

因此,如果有人遇到类似问题,请检查您是否正确导入了 Format 实例;)