2013-04-14 21 views
7

Używam Play 2.1 JSON Reads, aby uzyskać transformację warunkową.Odtwórz opcjonalny transformator JSON

Mam obiekt json i chcę przekształcić opcjonalne pole usuwające \ n znaków. Problem polega na tym, że jeśli usunę zawartość z wysłanego JSON, otrzymam błąd sprawdzania poprawności.

To pole jest opcjonalne i nie wiem, jak opisać, że przekształcenie jest opcjonalne. Jest obecna transformacja treści:

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

Jak mogę uzyskać opcjonalną transformację w terenie? Czy powinienem używać Reads.verifyingIf?

Dzięki

Odpowiedz

8

Można to zrobić:

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},) 

Mała hacky, ale działa.

+1

'readOpt' przestarzałe (od wersji 2.1-RC2) użyj zamiast tego' readNullable [T] '(które zarządza zarówno brakującymi, jak i zerowymi polami) – HEX

2

Kilka lat później musiałem zmienić kilka rzeczy, aby to działało:

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},) 

Odczyt nie powiedzie, jeśli ciąg nie jest obecne, a zatem metody OrElse Handels się JsError.