Добавьте дополнительные поля после десериализации json с использованием play-json-extensions - PullRequest
0 голосов
/ 23 апреля 2019

У меня есть класс дел, который имеет более 22 параметров.

case class Model(a1: Int,
                   a2: Int,
                   a3: Int,
                   a4: Int,
                   a5: Int,
                   a6: Int,
                   a7: Int,
                   a8: Int,
                   a9: Int,
                   a10: Int,
                   a11: Int,
                   a12: Int,
                   a13: Int,
                   a14: Int,
                   a15: Int,
                   a16: Int,
                   a17: Int,
                   a18: Int,
                   a19: Int,
                   a20: Int,
                   a21: Int,
                   a22: Int,
                   a23: Int,
                   a24: Int)

Я получаю вход json, который мне нужно десериализовать в вышеупомянутый класс дел Model.Но мой ввод json не содержит полей a1 и a2.Мой json выглядит примерно так

  {
  "a3": 3,
  "a4": 4,
  "a5": 5,
  "a6": 6,
  "a7": 7,
  "a8": 8,
  "a9": 9,
  "a10": 10,
  "a11": 11,
  "a12": 12,
  "a13": 13,
  "a14": 14,
  "a15": 15,
  "a16": 16,
  "a17": 17,
  "a18": 18,
  "a19": 19,
  "a20": 20,
  "a21": 21,
  "a22": 22,
  "a23": 23,
  "a24": 24
}

Теперь, чтобы справиться с этой ситуацией, я написал свой пользовательский считыватель json, который добавил бы некоторые фиктивные значения для полей a1 и a2 в json.

У меня есть собственный метод, чтобы добавить поля для ввода JSON, который читается.Метод расширения addField выглядит следующим образом

implicit class ReadOps[A](reads: Reads[A]) {
    def addField(fieldName: String, value: Int): Reads[A] = Reads {
      json: JsValue =>
        json
          .validate(__.json.update((__ \ fieldName).json.put(JsString(value.toString))))
          .map(_.asInstanceOf[A])
    }
  }

Мой неявный формат json выглядит следующим образом

 implicit val jsonFormat = new OFormat[Model] {

    override def reads(json: JsValue): JsResult[Model] = {
      Jsonx.formatCaseClass[Model].addField("a1",1).addField("a2",2).reads(json)
    }

    override def writes(o: Model): JsObject = {
      Jsonx.formatCaseClass[Model].writes(o)
    }
  }

Проблема, с которой я сталкиваюсь

Несмотря на двойной вызов метода addField (я пытаюсь добавить a1 со значением 1 и a2 со значением 2), только поле a1 со значением 1 добавляется в json, а a2 игнорируется.И json не десериализован в класс случая модели.

Я использую следующую зависимость

libraryDependencies += "ai.x" %% "play-json-extensions" % "0.30.1"

Пожалуйста, дайте мне знать, где я ошибаюсь в этом подходе.Любые указатели будут очень полезны.Заранее спасибо !!!

Примечание: - Пожалуйста, не предлагайте решения, такие как добавление a1 и a2 в качестве полей в классе модели.Это не подлежит сомнению, поскольку моя настоящая проблема довольно сложна, и этот вопрос о стековом потоке является очень упрощенной версией рассматриваемой проблемы.

1 Ответ

0 голосов
/ 23 апреля 2019

Рассмотрим добавление поля в новую ветку через JsPath.update:

 val js = Json.obj("key1" -> "value1", "key2" -> "value2")
 js.validate(__.json.update((__ \ 'key3).json.put(JsString("value3"))))
 => JsSuccess({"key1":"value1","key2":"value2","key3":"value3"},)

Вот рабочий пример

import ai.x.play.json.Jsonx
import play.api.libs.json.Json
import play.api.libs.json._

case class Foo(a1: Int, a2: Int, a3: Int, a4: Int, a5: Int, a6: Int, a7: Int, a8: Int, a9: Int, a10: Int, a11: Int, a12: Int, a13: Int, a14: Int, a15: Int, a16: Int, a17: Int, a18: Int, a19: Int, a20: Int, a21: Int, a22: Int, a23: Int, a24: Int)

object Foo {
  implicit val format = Jsonx.formatCaseClass[Foo]
}

object AddFieldsToDeserialisation extends App {
  val raw =
    """
      |{
      |  "a3": 3,
      |  "a4": 4,
      |  "a5": 5,
      |  "a6": 6,
      |  "a7": 7,
      |  "a8": 8,
      |  "a9": 9,
      |  "a10": 10,
      |  "a11": 11,
      |  "a12": 12,
      |  "a13": 13,
      |  "a14": 14,
      |  "a15": 15,
      |  "a16": 16,
      |  "a17": 17,
      |  "a18": 18,
      |  "a19": 19,
      |  "a20": 20,
      |  "a21": 21,
      |  "a22": 22,
      |  "a23": 23,
      |  "a24": 24
      |}
    """.stripMargin


  val json = Json.parse(raw)
  val updatePutTransformation = 
    (field: String, value: Int) =>  __.json.update((__ \ field ).json.put(JsNumber(value)))
  val addedFields =
    List("a1" -> 1, "a2" -> 2)
      .map { case (field, value) => updatePutTransformation(field, value) }
      .reduce((putUpdate1, putUpdate2) => putUpdate1 andThen putUpdate2 )
  val jsonWithPutValue = json.transform(addedFields)
  println(jsonWithPutValue.get)
  println(jsonWithPutValue.get.as[Foo])


}

должен вывести

{ "a1": 1, "a2": 2, "a3": 3, "a4": 4, "a5": 5, "a6": 6, "a7": 7, "a8": 8, "a9": 9, "a10": 10, "a11": 11, "a12": 12, "a13": 13, "a14": 14, "a15": 15, "a16": 16, "a17": 17, "a18": 18, "a19": 19, "a20": 20, "a21": 21, "a22": 22, "a23": 23, "a24": 24 }

Foo(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...