2013-04-14 15 views
7

Utilizzo le letture JSON Play 2.1 per ottenere una trasformazione condizionale.Riproduci trasformatore opzionale JSON

Ho un oggetto json e voglio trasformare un campo opzionale rimuovendo \ n caratteri. Il problema è che se rimuovo il contenuto dal JSON inviato, ottengo un errore di convalida.

Questo campo è facoltativo e non so come descrivere che la trasformazione è facoltativa. Questa è l'attuale trasformazione dei contenuti:

 val transformContent = (__ \ 'content).json.update(__.read[JsString].map{ 
     value => 
     JsString(value.value.replaceAll("\n", "")) 
    }) 

Come posso ottenere un campo di trasformazione facoltativa? Dovrei usare lo Reads.verifyingIf?

Grazie

risposta

8

si può fare questo:

val json = Json.obj("whatever" -> 1, "content" -> "hello world") 
val json2 = Json.obj("whatever" -> 1) 

val transformer = (__ \ 'content).json.update(
    __.readOpt[JsString].map{ 
    case Some(JsString(str)) => JsString(str.replaceAll("world", "scala")) 
    } 
).orElse(__.json.pick[JsObject]) 

json.transform(transformer) 
//JsSuccess({"whatever":1,"content":"hello scala"},) 
json2.transform(transformer) 
//JsSuccess({"whatever":1},) 

Piccolo hacky, ma funziona.

+1

'readOpt' deprecato (dalla versione 2.1-RC2) usa invece' readNullable [T] '(che gestisce sia i campi mancanti che null) – HEX

2

Qualche anno dopo ho dovuto cambiare alcune cose per farlo funzionare:

val json = Json.obj("whatever" -> 1, "content" -> "hello world") 
val json2 = Json.obj("whatever" -> 1) 

val transformer = (__ \ 'content).json.update(
    __.read[JsString].map { 
    case JsString(str) => JsString(str.replaceAll("world", "scala")) 
    } 
).orElse(__.json.pick[JsObject]) 

json.transform(transformer) 
//JsSuccess({"whatever":1,"content":"hello scala"},) 
json2.transform(transformer) 
//JsSuccess({"whatever":1},) 

La lettura ha esito negativo se la stringa non è presente, così i metodi OrElse Handels il JsError.