假设我有一些带有一个字段的案例类
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
我已经read documentation ,但是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 字符串,请执行以下操作:
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")
我这样写是为了清楚地说明,除了基本的 String
格式化程序(在 play-json 中定义)之外,您无需使用其他任何东西。
关于scala - 如何为 scala 中具有一个字段的案例类编写对称 Play Json 格式化程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47276109/