Play Framework - 向JSON对象添加字段

Paw*_*ski 35 json scala playframework playframework-2.0

我在使用Scala在Play Framework中向Json对象添加字段时遇到问题:

我有一个包含数据的案例类.例如:

case class ClassA(a:Int,b:Int)
Run Code Online (Sandbox Code Playgroud)

我可以使用Json Writes创建一个Json对象:

val classAObject = ClassA(1,2)
implicit val classAWrites= Json.writes[ClassA]
val jsonObject = Json.toJson(classAObject)
Run Code Online (Sandbox Code Playgroud)

而Json看起来像:

{ a:1, b:2 }
Run Code Online (Sandbox Code Playgroud)

假设我想在Json对象中添加一个额外的'c'字段.结果:

{ a:1, b:2, c:3 }
Run Code Online (Sandbox Code Playgroud)

如何在不创建新案例类或使用Json.obj自己创建Json对象的情况下如何做到这一点?我正在寻找类似的东西:

jsonObject.merge({c:3}) 
Run Code Online (Sandbox Code Playgroud)

任何帮助赞赏!

Tra*_*own 43

JsObject有一个+方法,允许您向对象添加字段,但不幸的jsonObject是,您的静态类型为a JsValue,而不是a JsObject.你可以通过几种方式解决这个问题.首先是使用as:

 scala> jsonObject.as[JsObject] + ("c" -> Json.toJson(3))
 res0: play.api.libs.json.JsObject = {"a":1,"b":2,"c":3}
Run Code Online (Sandbox Code Playgroud)

随着as你基本上向下转换-你告诉编译器,"你只知道这是一个JsValue,但相信我,这也是一个JsObject".在这种情况下这是安全的,但这不是一个好主意.更有原则的方法是OWrites直接使用:

scala> val jsonObject = classAWrites.writes(classAObject)
jsonObject: play.api.libs.json.JsObject = {"a":1,"b":2}

scala> jsonObject + ("c" -> Json.toJson(3))
res1: play.api.libs.json.JsObject = {"a":1,"b":2,"c":3}
Run Code Online (Sandbox Code Playgroud)

也许有一天,Json对象将有一个toJsonObject需要OWrites实例的方法,这种过于明确的方法就没有必要了.

  • @elmalto尝试一下``classWrites`将静态输入为`OWrites [ClassA]`(在Play 2.2和2.3以及2.10和2.11中).这是由于Scala宏的"未指定但有意"的行为(有关详细信息,请参阅我的问题[此处](http://stackoverflow.com/q/13669974/334519)). (2认同)

Paw*_*ski 8

我自己找到了解决方案.实际上JsValue,它是Json.toJson的返回类型,没有这样的方法,但是JsObject(http://www.playframework.com/documentation/2.2.x/api/scala/index.html#play.api) .libs.json.JsObject),所以解决方案是:

val jsonObject = Json.toJson(classAObject).as[JsObject]
jsonObject + ("c", JsNumber(3)) 
Run Code Online (Sandbox Code Playgroud)

我希望有人能发现这个有用:)