鉴于此范围类:
case class Range(things: (String, String))
我尝试在Writes[Range]
上的Play Json docs示例中实现Creature
。
implicit val rangeWrites: Writes[Range] =
(JsPath \ "things").write(
(JsPath \ "string").write[String] and
(JsPath \ "string").write[String]
tupled
)(unlift(Range.unapply))
然而,我得到了:
[error] JsonTest.scala 19 could not find implicit value for
parameter app: play.api.libs.functional.
Applicative[play.api.libs.json.OWrites]
[error] (JsPath \ "items").write(
如何正确填写(JsPath \ "items").write(
?在文档的示例中,似乎没有任何类型需要。
答案 0 :(得分:3)
此处的问题与this question中显示的问题非常类似:您无法在普通的Writes
(或OWrites
)上使用适用语法 - 您需要Builder
。
此处的解决方案也类似,但您需要map
而不是contramap
,因为Writes
是一个逆变函子,而不是仿函数:
implicit val rangeWrites: Writes[Range] =
(JsPath \ "things").write(
(JsPath \ "string1").write[String] and
(JsPath \ "string2").write[String]
tupled
).contramap(unlift(Range.unapply))
另请注意,我已将密钥更改为string1
和string2
- 如果您使用相同的密钥,则无法获得预期效果。
答案 1 :(得分:1)
另一种方法是直接实现Writes trait,这样可以更好地控制对象如何转换为JSON。
示例:
implicit object RangeWrites extends Writes[Range] {
def writes(value: Range): JsValue = {
Json.obj("things" -> Json.arr(value.things._1, value.things._2))
}
}
为对象提供以下JSON:{"things":["hello","all"]}
:Range(("hello", "all"))