Tengo un problema con agregar un campo a un objeto Json en el Juego de Marco con Scala:

Tengo un caso de la clase que contiene los datos. Por ejemplo:

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

y soy capaz de crear un objeto Json usando Json Escribe:

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

y el Json que se vería como:

{ a:1, b:2 }

Supongamos que me gustaría agregar un adicional de ‘c’ de campo para el objeto Json. Resultado:

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

¿Cómo puedo hacer esto sin crear un caso nuevo de la clase o de la creación de mi objeto Json a mí mismo usando Json.obj? Estoy buscando algo como:

jsonObject.merge({c:3}) 

Cualquier ayuda apreciada!

3 Comentarios

  1. 39

    JsObject tiene un + método que le permite agregar campos a un objeto, pero, lamentablemente, su jsonObject es de tipo estático como un JsValue, no JsObject. Usted puede conseguir alrededor de esto en un par de maneras. La primera es el uso de as:

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

    Con as básicamente estás downcasting—estás diciendo al compilador, «sólo sé que este es un JsValue, pero créanme, es también un JsObject«. Esto es seguro en este caso, pero no es una buena idea. Una más basada en los principios del enfoque es el uso de la OWrites directamente:

    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}

    Tal vez algún día la Json objeto tendrá un toJsonObject método, que requerirá de un OWrites instancia y esta demasiado explícito enfoque no será necesario.

    • Por la firma, Writes.writes devuelve JsValue, así que no entiendo cómo usted puede deshacerse de upcasting (no en el REPL).
    • Tvaroh es correcto, volver JsValue tan lejos como puedo ver
    • Pruébelo—classAWrites será de tipo estático como OWrites[ClassA] (en ambos Juegan 2.2 y 2.3 y en 2.10 y 2.11). Esto es debido a la «underspecified pero la intención de» comportamiento de la librería de macros (ver mi pregunta aquí para obtener más detalles).
    • Saltarse la definición de la clase y escritor de la brevedad, pero esto es lo que el repl me da: scala> SessionCreatorWriter.writes(s) res2: play.api.libs.json.JsValue
    • Si se define un Writes instancia obtendrá JsValue, pero si define un OWrites instancia—ya sea manualmente o utilizando el Json.writes macro, que es lo que el OP está haciendo obtendrás un JsObject.
    • tal vez yo debería haber publicado a continuación: implicit val SessionCreatorWriter = Json.writes[SessionCreator] val s = SessionCreator("User1",None,None,None,1,None,None) SessionCreatorWriter.writes(s) y me sale un JsValue
    • De hecho, no existe necesidad de que el paranthesis. Esto funciona: jsobj + "key" -> entity.key
    • Que hace algo completamente diferente. + y - tienen la misma prioridad, por lo que los paréntesis son sin duda necesarias.
    • Tienes razón, y yo soy más sabio ahora, gracias!
    • No funciona para mí !

  2. -1

    manera más sencilla es utilizar 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

    aquí obj1.asJson crea un objeto JSON
    y obj2 es el objeto a ser añadido a la json creado por obj1.asJson

Dejar respuesta

Please enter your comment!
Please enter your name here