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})
Любая помощь оценивается!
Ответы
Ответ 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