Как заменить значение JSON в Play
Как заменить значение в значении JSON в Play?
Код для иллюстрации:
def newReport() = Action(parse.json) { request =>
var json = request.body
if((json \ "customerId").as[Int] == -1){
// replace customerId after some logic to find the new value
}
json.validate[Report](Reports.readsWithoutUser).map {
case _: Report =>
Ответы
Ответ 1
Согласно документации Play, у JsObjects есть метод ++
, который объединит два JsObject. Итак, когда у вас есть новое целочисленное значение, вам просто нужно:
val updatedJson = json.as[JsObject] ++ Json.obj("customerId" -> newValue)
Начиная с Play 2.4.x вы можете использовать +
:
val updatedJson = json.as[JsObject] + ("customerId" -> newValue)
(ПРИМЕЧАНИЕ: метод +
был добавлен уже в 2.1.x, но добавляет дублирующее поле к объекту вместо замены существующего значения в версиях до 2.4.x)
Ответ 2
Что-то по строкам:
val updatedJson = if((request.body \ "customerId").as[Int] == -1){
val newId = JsObject(Seq(("customerId",JsString("ID12345"))))
(request.body ++ newId).as[JsValue]
} else request.body
updatedJson.validate[Report](Reports.readsWithoutUser).map {
case _: Report =>
Ответ 3
Один из подходов, как говорит Марк Б, преобразовать JSON в нечто вроде класса case, манипулировать этим, а затем создать новый JSON.
Однако вы также можете использовать трансформаторы JSON. Эффективно, что вы делаете, это создать объект Reads [SomeThing]. Этот объект передается методу преобразования, который вы вызываете на свой объект JSON. Он изменит объект JSON и вернет Success (результат) или Failure (ошибка), где результатом будет новый модифицированный JSON. Здесь (сравнительно) очень простой пример:
с использованием json формата: {key → value}
def jsonXForm(value: String) = (__ \ "customerId").json.update(
(__ \ "customerId").json.put(JsString(value))
)
json.transform(jsonXForm(yourNewValue)) match {...}`
Существует достойный путеводитель здесь
Ответ 4
Я рассматриваю возможность отказаться от всех тех непреложных решений JSON. Это просто делает код ужасным беспорядком. Вот как это выглядело бы в SON of JSON:
import nl.typeset.sonofjson._
val json = …
if (json.customerId.as[Int] == -1) {
json.customerId = 987938
}
Ответ 5
прославленная версия ответа Zeimyth, использующая неявное преобразование
implicit class JsObjectEnhancer(jsObject: JsObject) {
def update(args: (String, Json.JsValueWrapper)*): JsObject = {
jsObject ++ Json.obj(args: _*)
}
}
use (json должен иметь тип JsObject и неявный класс должен быть в области)
json.update("customerId", 1000)