Json.writes [List [Foo]]为“map”

时间:2014-11-14 07:42:04

标签: json scala playframework playframework-2.3

我有一个case class Foo(bars: List[Bar])作为带有数组的对象通过Json初始呈现为json:

{"bars": [
   { 
     "key: "4587-der",
     "value": "something" 
   }
 ]
}

但我想将bars: List[Bar]渲染为“地图”,其中Bar.key用作关键字:

{"bars":{
    "4587-der": {
      "value": "something"
    }
  }
}

如何在不修改我的案例类Foo的情况下获得它?

非常感谢

1 个答案:

答案 0 :(得分:1)

您可以通过扩展Writes并为其实施Bar方法为Writes[Bar]定义writes

case class Bar(key: String, value: String)

implicit object BarWrites extends Writes[Bar] {
    def writes(bar: Bar): JsValue = Json.obj(
        bar.key -> Json.obj("value" -> bar.value)
    )
}

scala> Json.stringify(Json.toJson(Bar("4587-der", "something")))
res0: String = {"4587-der":{"value":"something"}}

对于那些可能感兴趣的人,这里是[{1}}:

的(某种程度上)粗略的实现
Reads[Bar]

编辑,因为OP希望将implicit object BarReads extends Reads[Bar] { def reads(js: JsValue): JsResult[Bar] = js match { case JsObject(Seq((key, JsObject(Seq(("value", JsString(value))))))) => JsSuccess(Bar(key, value)) case _ => JsError(Seq()) } } scala> Json.parse(""" [{"4587-der":{"value": "something"}}] """).validate[List[Bar]] res11: play.api.libs.json.JsResult[List[Bar]] = JsSuccess(List(Bar(4587-der,something)),) 合并到一个对象而不是一个数组中:

您还必须定义一个特殊的Bar

Writes[List[Bar]]