【问题标题】:How to write a symmetric Play Json formatter for a case class with one field in scala? [duplicate]如何为scala中具有一个字段的案例类编写对称的Play Json格式化程序? [复制]
【发布时间】:2017-11-14 13:28:52
【问题描述】:

假设我有一个包含一个字段的案例类

case class Id(value: String)

简单地说,我可以通过分别定义读取和写入来定义格式化程序:

private implicit val idReads: Reads[Id] =
    JsPath.read[String].map(Id)

private implicit val idWrites: Writes[Id] =
{
    id: Id => JsString(id.value)
}

private idFormats: Format[Id] = Format(idReads, idWrites)

文档建议有一种方法可以为这种情况定义对称格式化程序,但我还没有找到使它适用于这种情况的特定咒语。我尝试了以下方法,但出现编译错误:

private implicit val idFormats: Format[Id] =
    JsPath.format[String](Id, unlift(Id.unapply))

具体来说,我得到了这个编译错误:

[error] overloaded method value format with alternatives:
[error]   (w: play.api.libs.json.Writes[String])(implicit r: play.api.libs.json.Reads[String])play.api.libs.json.OFormat[String] <and>
[error]   (r: play.api.libs.json.Reads[String])(implicit w: play.api.libs.json.Writes[String])play.api.libs.json.OFormat[String] <and>
[error]   (implicit f: play.api.libs.json.Format[String])play.api.libs.json.OFormat[String]
[error]  cannot be applied to (Id.type, Id => String)
[error]         JsPath.format[String](Id, unlift(Id.unapply))
[error]                      ^
[error] one error found
[error] (compile:compileIncremental) Compilation failed
[error] Total time: 1 s, completed Nov 13, 2017 5:07:58 PM

我有 readdocumentation,但 it 没有帮助我。我确信有一些单行可以应用于这种情况,因为它对于具有两个字段的案例类来说是微不足道的:

case class MyRow(id: Id, myNum: MyNum)

private implicit val myRowFormats: Format[MyRow] =
    ((JsPath \ "id").format[Id] and
        (JsPath \ "num").format[MyNum]) (MyRow, unlift(MyRow.unapply))

【问题讨论】:

  • 您真的希望您的 Id 类被序列化为 JSON 字符串,而不是 JSON 对象吗?

标签: scala playframework


【解决方案1】:

如果你真的希望 Id 被序列化为 JSON 字符串,你可以这样做:

import play.api.libs.json._
import play.api.libs.functional.syntax._

case class Id(value: String)

implicit val idFormats: Format[Id] =
  implicitly[Format[String]].inmap(Id, unlift(Id.unapply))

Json.toJson(Id("asd")) == JsString("asd")
Json.toJson(Id("asd")).toString == "\"asd\""
Json.parse(Json.toJson(Id("asd")).toString).as[Id] == Id("asd")

我这样写是为了清楚地说明,除了 play-json 中定义的基本String 格式化程序之外,您什么都不使用。

【讨论】:

  • 是的,作为 JsString。谢谢!隐式函数“inmap”是我正在寻找的。我希望 inmap 被记录为 2.6,而不仅仅是 2.1。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-14
  • 2015-03-25
  • 2023-03-26
  • 2022-01-27
  • 2018-10-19
相关资源
最近更新 更多