Scala Play Framework 2.6将特质格式密封为Json

时间:2018-10-31 15:08:29

标签: scala playframework

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

我有这个case类及其配套对象

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.toJson(payment)或作为json读取时将对象转换为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)
  }
}

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

  

隐式范围内的model.entities.EUR没有Reads实例

2 个答案:

答案 0 :(得分:3)

改为这样做:

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

}

答案 1 :(得分:1)

当我们最终在问题注释中解决了您的问题时,我在此处发布了固定注释作为答案:

以下错误:

  

以下版本中的model.entities.EUR没有Reads实例可用。   隐式范围

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

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

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