web-dev-qa-db-fra.com

Play Framework - ajouter un champ à un objet JSON

J'ai un problème avec l'ajout d'un champ à un objet Json dans Play Framework à l'aide de Scala:

J'ai une classe de cas contenant des données. Par exemple:

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

et je peux créer un objet Json en utilisant Json Writes:

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

et le Json ressemblerait à:

{ a:1, b:2 }

Supposons que je souhaite ajouter un champ "c" supplémentaire à l'objet Json. Résultat:

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

Comment faire sans créer une nouvelle classe de cas ou créer moi-même mon objet Json à l'aide de Json.obj? Je cherche quelque chose comme:

jsonObject.merge({c:3}) 

Toute aide appréciée!

35

JsObject a un + méthode qui vous permet d'ajouter des champs à un objet, mais malheureusement votre jsonObject est statiquement tapé comme JsValue, pas comme JsObject. Vous pouvez contourner cela de plusieurs manières. La première consiste à utiliser as:

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

Avec as, vous abattez essentiellement - vous dites au compilateur, "vous savez seulement que c'est un JsValue, mais croyez-moi, c'est aussi un JsObject". C'est sûr dans ce cas, mais ce n'est pas une bonne idée. Une approche plus raisonnée consiste à utiliser directement le OWrites:

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}

Peut-être qu'un jour l'objet Json aura une méthode toJsonObject qui nécessitera une instance OWrites et cette approche trop explicite ne sera pas nécessaire.

40
Travis Brown

J'ai trouvé moi-même une solution. En fait, le JsValue, qui est le type de retour de Json.toJson n'a pas une telle méthode, mais le JsObject ( http://www.playframework.com/documentation/2.2.x/api/scala/index.html # play.api.libs.json.JsObject ), donc la solution est:

val jsonObject = Json.toJson(classAObject).as[JsObject]
jsonObject + ("c", JsNumber(3)) 

J'espère que quelqu'un trouvera cela utile :)

8