2014-04-04 81 views
29

我有個問題與使用的Scala在播放框架添加一個字段,JSON對象:播放框架 - 將字段添加到JSON對象

我有一個包含數據的情況下類。例如:

case class ClassA(a:Int,b:Int) 

,我能夠創建使用JSON JSON對象寫入:

val classAObject = ClassA(1,2) 
implicit val classAWrites= Json.writes[ClassA] 
val jsonObject = Json.toJson(classAObject) 

並且json看起來像:

{ a:1, b:2 } 

讓我們假設我想向Json對象添加一個額外的'c'字段。結果:

{ a:1, b:2, c:3 } 

如何在不創建新的案例類或使用Json.obj自己創建Json對象的情況下執行此操作?我正在尋找類似的東西:

jsonObject.merge({c:3}) 

任何幫助讚賞!

回答

31

JsObject有一個+方法,允許您將字段添加到對象,但不幸的是,您的jsonObject靜態類型爲JsValue,而不是JsObject。你可以通過幾種方法解決這個問題。第一種方法是使用as

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

隨着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} 

也許有一天,在Json對象有一個toJsonObject方法,這將需要一個OWrites實例,這種過於明確的做法沒有必要。

+0

每簽名創建的JSON對象,'寫道。寫'返回'JsValue',所以我不明白你如何擺脫upcasting(不在REPL中)。 – Tvaroh

+0

Tvaroh是正確的,它返回JsValue,據我所見 – elmalto

+2

@elmalto試試吧''classAWrites'將靜態類型爲'OWrites [ClassA]'(在Play 2.2和2.3以及2.10和2.11中)。這是由於Scala宏的「未指定但意圖」的行爲(請參閱我的問題[here](http:// stackoverflow。com/q/13669974/334519)以獲得詳細信息)。 –

-1

簡單的方法是使用argoanut(http://argonaut.io/

var jField : Json.JsonField = "myfield" //Json.JsonField is of type String 
obj1.asJson.->:(jField, obj2.asJson) // adds a field to obj1.asJson 

這裏obj1.asJson創建一個JSON對象 和obj2將被添加到由obj1.asJson