2013-02-01 11 views
16

Come sostituire un valore in un valore JSON in Play?
Codice per illustrare:
Come sostituire un valore JSON in Play

def newReport() = Action(parse.json) { request => 
    var json = request.body 
    if((json \ "customerId").as[Int] == -1){ 
     // replace customerId after some logic to find the new value 
    } 
    json.validate[Report](Reports.readsWithoutUser).map { 
     case _: Report => 
+4

non manipolare le stringhe JSON. su quella strada giace la follia. si converte la stringa json in una struttura dati nativa, si manipola la struttura, quindi si ri-codifica in json. –

+0

Come MarcB, o utilizzare Json Coast2Coast presenta http://mandubian.com/2012/10/29/unveiling-play-2-dot-1-json-api-part3-json-transformers/ –

+1

Se [la mia risposta] (http://stackoverflow.com/a/18069519/2643828) è stato utile per te, selezionalo come risposta accettata. – Zeimyth

risposta

2

Qualcosa sulla falsariga di:

val updatedJson = if((request.body \ "customerId").as[Int] == -1){ 
    val newId = JsObject(Seq(("customerId",JsString("ID12345")))) 
    (request.body ++ newId).as[JsValue] 
} else request.body 

updatedJson.validate[Report](Reports.readsWithoutUser).map { 
    case _: Report => 
+0

Non è possibile aggiornare il valore in posizione poiché le strutture di dati di Play Json non sono modificabili, ma è possibile creare un nuovo JsValue identico ad eccezione del campo aggiornato. – scalapeno

25

Secondo il Play Documentation, JSObject hanno un metodo ++ che unire due JSObject. Così, quando si ha il nuovo valore intero, è sufficiente:

val updatedJson = json.as[JsObject] ++ Json.obj("customerId" -> newValue) 

Come of Play 2.1.x è possibile utilizzare +:

val updatedJson = json.as[JsObject] + ("customerId" -> newValue) 
1

sto valutando allontanamento tutti quelli immutabili Soluzioni "JSON". Sta solo rendendo il codice un pasticcio orribile. Questo è come dovrebbe apparire in SON of JSON:

import nl.typeset.sonofjson._ 

val json = … 
if (json.customerId.as[Int] == -1) { 
    json.customerId = 987938 
} 
2

Un approccio è, come dice Marc B, convertire il JSON a qualcosa come una classe case, manipolare questo, e quindi creare un nuovo JSON.

Tuttavia è possibile utilizzare anche i "trasformatori" JSON. In effetti quello che fai è costruire un oggetto Reads [SomeThing]. Questo oggetto è passato al metodo di trasformazione che tu chiami sul tuo oggetto JSON. Cambierà l'oggetto JSON e restituirà un successo (risultato) o un errore (errore) dove il risultato è il nuovo JSON modificato. Ecco un (relativamente) molto semplice esempio:

utilizzando JSON di formato: {key -> valore}

def jsonXForm(value: String) = (__ \ "customerId").json.update(
    (__ \ "customerId").json.put(JsString(value)) 
) 
json.transform(jsonXForm(yourNewValue)) match {...}` 

C'è un decente guida here

0

una versione glorificata di Zeimyth di risposta che utilizza la conversione implicita

implicit class JsObjectEnhancer(jsObject: JsObject) { 
    def update(args: (String, Json.JsValueWrapper)*): JsObject = { 
    jsObject ++ Json.obj(args: _*) 
    } 
} 

utilizzo (JSON deve essere di tipo JSObject e la classe implicita dovrebbe essere di portata)

json.update("customerId", 1000) 
Problemi correlati