一种选择是捕获 a 中的“未知”字段,Map[String,JsValue]以后可以在需要时从中提取值。
case class MyClass(a: String, b: String, c: String, extra: Map[String, JsValue])
implicit val reads: Reads[MyClass] = (
(__ \ "a").read[String] and
(__ \ "b").read[String] and
(__ \ "c").read[String] and
__.read[Map[String, JsValue]]
.map(_.filterKeys(k => !Seq("a", "b", "c").contains(k)))
)(MyClass.apply _)
// Result:
// MyClass(aa,bb,cc,Map(e -> {"aa":"aa"}, d -> "dd"))
同样,您可以这样Writes做Format:
// And a writes...
implicit val writes: Writes[MyClass] = (
(__ \ "a").write[String] and
(__ \ "b").write[String] and
(__ \ "c").write[String] and
__.write[Map[String, JsValue]]
)(unlift(MyClass.unapply _))
// Or combine the two...
implicit val format: Format[MyClass] = (
(__ \ "a").format[String] and
(__ \ "b").format[String] and
(__ \ "c").format[String] and
__.format[Map[String, JsValue]](Reads
.map[JsValue].map(_.filterKeys(k => !Seq("a", "b", "c").contains(k))))
)(MyClass.apply, unlift(MyClass.unapply))
注意:它看起来有点令人困惑,因为您将formatforMap[String,JsValue]显式Reads作为参数 ( Reads.map),然后您对其进行转换(使用.map 方法)以删除已经捕获的值。