Подтвердить что ты не робот

Play Framework - добавление поля в объект JSON

У меня проблема с добавлением поля к объекту Json в Play Framework с помощью Scala:

У меня есть класс case, содержащий данные. Например:

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

и я могу создать объект Json с помощью Json Writes:

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

и Json будет выглядеть так:

{ a:1, b:2 }

Предположим, что я хотел бы добавить дополнительное поле "c" к объекту Json. Результат:

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

Как мне это сделать, не создавая новый класс case или не создавая сам объект Json, используя Json.obj? Я ищу что-то вроде:

jsonObject.merge({c:3}) 

Любая помощь оценивается!

4b9b3361

Ответ 1

JsObject имеет метод +, который позволяет добавлять поля к объекту, но, к сожалению, ваш jsonObject статически вводится как JsValue, а не JsObject. Вы можете обойти это несколькими способами. Во-первых, используйте as:

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

С as вы по сути опускаетесь, вы говорите компилятору: "Вы только знаете, что это JsValue, но поверьте мне, это также JsObject". В этом случае это безопасно, но это не очень хорошая идея. Более принципиальный подход заключается в непосредственном использовании 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}

Возможно, когда-нибудь объект Json будет иметь метод toJsonObject, для которого потребуется экземпляр OWrites, и этот чрезмерно явный подход не понадобится.

Ответ 2

Я нашел решение самостоятельно. На самом деле JsValue, который является возвращаемым типом Json.toJson, не имеет такого метода, но JsObject (http://www.playframework.com/documentation/2.2.x/api/scala/index.html#play.api.libs.json.JsObject), поэтому решение:

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

Я надеюсь, что кто-то найдет это полезным:)

Ответ 3

Более простой способ - использовать 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

здесь obj1.asJson создает объект JSON и obj2 - это объект, который должен быть добавлен в json, созданный obj1.asJson