【问题标题】:Scala Play Framework 2.6 sealed trait format to JsonScala Play Framework 2.6 密封特征格式到 Json
【发布时间】:2019-04-04 19:23:28
【问题描述】:

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

我有这个案例类和它的伴生对象

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

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

在隐式范围内没有可用于 models.entities.EUR 的读取实例

【问题讨论】:

  • currency.toString 不是返回 "EUR" 而不是 "eur" 吗?我认为这可能是您所说的错误。如果是,我会将此评论更改为答案,否则,您能否更准确地了解您的问题是什么? (通过举例说明您期望的结果/您当前获得的结果)
  • @Argurth 感谢您的阅读和评论。我更新了问题,希望我回答了你的问题。
  • 谢谢!您是否正确导入了尝试将 EUR 转换为 json 的 Format 实例?例如implicit lazy val currencyFormat: Format[Currency] = Currency.CurrencyFormat ?
  • @Argurth 谢谢!!!现在是这样,现在它正在工作
  • @angusgambina 不客气!我将评论发布为答案,因此您可以将其标记为可能面临相同问题的未来用户的可接受答案:)

标签: scala playframework


【解决方案1】:

改为这样:

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

}

【讨论】:

  • 感谢您的回答,现在它正在与implicit val paymentFormat = Json.format[Payment]合作
【解决方案2】:

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

以下错误:

没有适用于 models.entities.EUR 的 Reads 实例 隐式作用域

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-06-05
    • 2015-05-26
    • 1970-01-01
    • 2015-09-17
    • 2017-09-08
    • 2018-12-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多