我有一个包含 10 多个字段的大案例类,代表来自用户的 JSON 有效负载。大多数字段都是可选的,因此在这种情况下我使用 Option
(Option[String]
对于字符串字段。这是一个很好的方法,直到我需要一个可选序列.我认为编写 Option[Seq[String]] 很奇怪,因为空序列足以表明没有数据(出于任何原因)。
不过,我可以通过手动方式处理它:
implicit val reads = new Reads[MyCaseClass] {
def reads(js: JsValue): JsResult[MyCaseClass] = {
JsSuccess(MyCaseClass(
(js \ "unit_code").as[String],
// other fields omited
(js \ "positions").asOpt[Seq[String]] match {
case Some(seq: Seq[String]) => seq
case None => Seq.empty[String]
}
))
}
}
但我不想手动编写所有这些内容。可能会有错误,我需要单独测试它,当然,这比编写 implicit val f = Json.format[MyCaseClass]
花费更多时间。
是否有任何选项可以单独处理一个字段,而其他字段则在默认宏上处理 let ?
最佳答案
感谢用户“cchantep”指向 Json transformers 。 这就是我解决问题的方法:
案例类别:
case class MyCaseClass(unit_code: String, positions: Seq[String] = Seq.empty)
伴随对象
object MyCaseClass {
private val readsTransformer: Reads[JsObject] = __.json.update(
__.read[JsObject]
.map{ o =>
if (o.keys.exists(p => p.equals("positions"))) {
o
} else {
o ++ Json.obj("positions" -> JsArray())
}
}
)
implicit val readsImplicit: Reads[MyCaseClass] = readsTransformer.andThen(Json.reads[MyCaseClass])
implicit val writesImplicit: OWrites[MyCaseClass] = Json.writes[MyCaseClass]
}
这看起来有点麻烦,但是可以编写为精确字段创建变压器的通用函数,因此在每个伴随对象中它不会那么冗长。
关于json - Scala/Play : modify Json. 单个字段的格式宏行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48115419/