2014-04-04 3 views
29

Ho un problema con l'aggiunta di un campo per oggetto JSON in Play Framework utilizzando Scala:quadro Gioco - aggiungere un campo per JSON oggetto

Ho una classe cassa che contiene i dati. Per esempio:

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

e sono in grado di creare un oggetto JSON utilizzando JSON scrive:

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

e JSON sarà simile:

{ a:1, b:2 } 

Supponiamo vorrei aggiungi un ulteriore campo "c" all'oggetto Json. Risultato:

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

Come faccio a farlo senza creare una nuova classe caso o la creazione di mia JSON oggetto me stesso usando Json.obj? Sto cercando qualcosa come:

jsonObject.merge({c:3}) 

Qualsiasi aiuto apprezzato!

risposta

31

JsObject ha un metodo + che consente di aggiungere campi a un oggetto, ma sfortunatamente il tuo jsonObject è staticamente digitato come JsValue, non uno JsObject. Puoi aggirare questo in un paio di modi. Il primo è quello di utilizzare as:

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

Con as si sta essenzialmente downcasting-tu sei raccontare il compilatore, "si conosce solo che questo è un JsValue, ma mi creda, è anche un JsObject". Questo è sicuro in questo caso, ma non è una buona idea. Un approccio più di principio è quello di utilizzare il OWrites direttamente:

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} 

Forse un giorno l'oggetto Json avrà un metodo toJsonObject che richiederà un'istanza OWrites e questo approccio troppo espliciti non sarà necessario.

+0

Per la firma, 'Scrive. writes' restituisce 'JsValue', quindi non capisco come si possa sbarazzarsi di upcasting (non in REPL). – Tvaroh

+0

Tvaroh ha ragione, restituisce JsValue per quello che posso vedere – elmalto

+2

@elmalto Provalo-'classAWrites' verrà staticamente digitato come 'OWrites [ClassA]' (sia in Play 2.2 che in 2.3 e in 2.10 e 2.11). Ciò è dovuto al comportamento "sottodecificato ma previsto" delle macro di Scala (vedere la mia domanda [qui] (http: // StackOverflow.it/q/13669974/334519) per i dettagli). –

-1

più semplice modo è quello di utilizzare 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 

qui obj1.asJson crea un oggetto JSON e obj2 è l'oggetto da aggiungere al JSON creato da obj1.asJson