2014-04-04 14 views
29

Mam problem z dodaniem pola do obiektu JSON w grze Framework za pomocą Scala:play Framework - dodać pole do JSON obiektu

Mam klasy obudowy zawierającej dane. Na przykład:

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

i jestem w stanie utworzyć obiekt JSON za pomocą JSON pisze:

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

i JSON wyglądałby następująco:

{ a:1, b:2 } 

Załóżmy, chciałbym dodaj dodatkowe pole "c" do obiektu Json. Rezultat:

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

Jak to zrobić, bez tworzenia nowej klasy przypadków lub tworzenia własnego obiektu Json za pomocą Json.obj? Szukam czegoś takiego:

jsonObject.merge({c:3}) 

Każda pomoc doceniona!

Odpowiedz

31

ma metodę +, która pozwala dodawać pola do obiektu, ale niestety twój jsonObject jest statycznie wpisany jako JsValue, a nie JsObject. Możesz obejść to na kilka sposobów. Pierwszym jest użycie as:

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

Z as jesteś zasadniczo rzutowanie w dół-you're informując kompilator, „znasz tylko, że jest to JsValue, ale wierzcie mi, jest to również JsObject”. W tym przypadku jest to bezpieczne, ale nie jest to dobry pomysł. Bardziej pryncypialne podejście jest użycie OWrites bezpośrednio:

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} 

Może kiedyś przedmiotem Json będzie mieć metodę toJsonObject że będzie wymagało OWrites instancji i to zbyt wyraźne podejście nie będzie konieczne.

+0

Per podpisu, 'pisze. write' zwraca 'JsValue', więc nie rozumiem, jak możesz się pozbyć upcastingu (nie w REPL). – Tvaroh

+0

Tvaroh ma rację, zwraca JsValue tak daleko, jak widzę. – elmalto

+2

@elmalto Wypróbuj - -classAWrites' będzie statycznie wpisane jako 'OWrites [ClassA]' (zarówno w wersji 2.2 i 2.3, jak i 2.10 i 2.11). Wynika to z "niedookreślonego, ale zamierzonego" zachowania makr Scali (zobacz moje pytanie [tutaj] (http: // stackoverflow.com/q/13669974/334519) w celu uzyskania szczegółowych informacji). –

-1

prostszym sposobem jest użycie 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 

tutaj obj1.asJson tworzy obiekt JSON i obj2 jest przedmiotem mają być dodane do JSON utworzonego przez obj1.asJson