Как отобразить вложенные значения, чтобы выровнять сложную структуру данных json - Groovy - PullRequest
0 голосов
/ 06 июля 2018

Наличие такого json - "Config.json":

{
    "Configuration" :

      {
        "_id" :
          { "id" : 40,
            "version" : 100
          },
        "companyCode" : "AB",
        "crewType" : "STANDARD",
        "modifiedByStaffId" : "12030405",
        "lastModifiedTimestamp" : "2018-07-04T12:17:21Z",
        "offDaysAllowed" : true,
        "daysAllowed" :
          { "max" : 5,
            "min" : 1
          },
        "offDayQuota" :
          { "per" : "month",
            "value" : 20
          },
        "requestWindow" :
          { "opens" :
            {
              "value" : 1,
              "unit" : "day"
            },
            "closes" :
            {
              "value" : 2,
              "unit" : "month"
            }
          },
        "reasons" : [ "wedding", "funeral", "illness" ],
        "supportingDocuments" :
          {
            "email" : "samplemail@gmail.com",
            "canSubmit" : true
          },
        "changeReasonCode" : "TODR"
      }
  }

Проблема: Я получаю ответ json, затем я хочу изменить его вложенные значения и отправить его обратно,поэтому я хочу создать экземпляр объекта из этого файла "Config.json" и иметь возможность легко устанавливать / изменять и получать его вложенные значения.Например config.setDaysAllowed_Max (4)

Согласно этой статье: http://www.baeldung.com/jackson-nested-values

Я пытался использовать метод «Сопоставление с аннотациями» с использованием JsonProperty, поэтому у меня есть Config.groovy class:

   class OffDayConfig {

        Object configuration
        Integer id
        Integer version
        String companyCode
        String crewType
        String modifiedByStaffId
        String lastModifiedTimestamp
        boolean offDaysAllowed
        Integer daysAllowed_Max
        Integer daysAllowed_Min
        String offDayQuota_Per
        Integer offDayQuota_Value
        Integer opensValue
        String opensUnit
        Integer closesValue
        String closesUnit
        List<String> reasons
        String supportingDocumentsEmail
        String supportingDocumentsCanSubmit
        String changeReasonCode

        @SuppressWarnings("unchecked")
        @JsonProperty("configuration")
        def unpackNested(Object configuration) {
            Map<String, Integer> _id = (Map<String, Integer>) configuration._id
            this.id = _id.get("id")
            this.version = _id.get("version")

            this.companyCode = configuration.get("companyCode")
            this.crewType = configuration.get("crewType")
            this.modifiedByStaffId = configuration.get("modifiedByStaffId")
            this.lastModifiedTimestamp = configuration.get("lastModifiedTimestamp")
            this.offDaysAllowed = configuration.get("offDaysAllowed")

            Map<String, Integer> daysAllowed = (Map<String, Integer>) configuration.get("daysAllowed ")
            this.daysAllowed_Max = daysAllowed.get("daysAllowed_Max")
            this.daysAllowed_Min = daysAllowed.get("daysAllowed_Min")

            Map<String, Object> offDayQuota = (Map<String, Object>) configuration.get("offDayQuota")
            this.offDayQuota_Per = offDayQuota.get("per")
            this.offDayQuota_Value = offDayQuota.get("value")

            Map<String, Object> requestWindow = (Map<String, Object>) offDayQuota.get("requestWindow")
            Map<String, Object> opens = (Map<String, Object>) requestWindow.get("opens")
            this.opensValue = opens.get("value")
            this.opensUnit = opens.get("unit")


            Map<String, Object> closes = (Map<String, Object>) requestWindow.get("closes")
            this.closesValue = closes.get("value")
            this.closesUnit = closes.get("unit")

            this.reasons = configuration.get("reasons")

            Map<String, Object> supportingDocuments = (Map<String, Object>) configuration.get("supportingDocuments")
            this.supportingDocumentsEmail = supportingDocuments.get("email")
            this.supportingDocumentsCanSubmit = supportingDocuments.get("canSubmit")

            this.changeReasonCode = configuration.get("changeReasonCode")
        }
    }

Затем я использую ObjectMapper для преобразования нашего исходного JSON, который существует как String "json" в тестовом классе:

Map offDayConfigMap = DataSource.getTestData(DataSourceType.OFF_DAY_CONFIG) //This line reads json file and creates the Map from it
String json = JsonOutput.toJson(offDayConfigMap)

OffDayConfig offDayConfig = new ObjectMapper().readerFor(OffDayConfig.class).readValue(json)

Но проблема возникает вметод readValue ().Я не могу понять, почему и в чем причина.Вот журнал:

        com.fasterxml.jackson.databind.JsonMappingException: Cannot invoke method get() on null object
        at [Source: (String)"{"Configuration":{"_id":{"id":40,"version":100},"changeReasonCode":"TODR","companyCode":"AB","crewType":"STANDARD","daysAllowed":{"max":5,"min":1},"lastModifiedTimestamp":"2018-07-04T12:17:21Z","modifiedByStaffId":"12030405","offDayQuota":{"per":"month","value":20},"offDaysAllowed":true,"reasons":["wedding","funeral","illness"],"requestWindow":{"closes":{"unit":"month","value":2},"opens":{"unit":"day","value":1}},"supportingDocuments":{"canSubmit":true,"email":"samplemail@gmail.com"}}}"; line: 1, column: 488] (through reference chain: ......................Config["Configuration"])

        at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:277)
        at com.fasterxml.jackson.databind.deser.SettableBeanProperty._throwAsIOE(SettableBeanProperty.java:588)
        at com.fasterxml.jackson.databind.deser.SettableBeanProperty._throwAsIOE(SettableBeanProperty.java:576)
        at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:134)
        at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:287)
        at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:151)
        at com.fasterxml.jackson.databind.ObjectReader._bindAndClose(ObjectReader.java:1608)
        at com.fasterxml.jackson.databind.ObjectReader.readValue(ObjectReader.java:1216)
        at ..................................Test.setupSpec(Test.groovy:42)
        Caused by: java.lang.NullPointerException: Cannot invoke method get() on null object
        at ..................................Config.unpackNested(Config.groovy:42)
        at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:132)
        ... 5 more

Точки представляют пакеты.

Буду признателен за помощь или совет, как это сделать по-другому, потому что мне нужен хороший способ сделать этопотому что у меня будет несколько файлов json для обработки таким образом.

Ответы [ 2 ]

0 голосов
/ 09 июля 2018

Благодаря ответу @Boaz я отладил свой код и обнаружил 3 ошибки:

Map<String, Integer> daysAllowed = (Map<String, Integer>) configuration.get("daysAllowed ") -> the space after "daysAllowed " -> "daysAllowed"

Map<String, Object> requestWindow = (Map<String, Object>) offDayQuota.get("requestWindow") -> Here I should write configuration.get("requestWindow") instead of  offDayQuota.get("requestWindow"), so "offDayQuota" -> "configuration"


this.daysAllowed_Max = daysAllowed.get("daysAllowed_Max") -> "max" instead of "daysAllowed_Max"
this.daysAllowed_Min = daysAllowed.get("daysAllowed_Min") -> "min" instead of "daysAllowed_Min"

Это работает, но я не знаю, как снова преобразовать этот плоский объект в тот же самый json.

0 голосов
/ 06 июля 2018

Просто быстрое предположение, NPE из-за

Map<String, Integer> daysAllowed = (Map<String, Integer>) configuration.get("daysAllowed ")
this.daysAllowed_Max = daysAllowed.get("daysAllowed_Max")
this.daysAllowed_Min = daysAllowed.get("daysAllowed_Min")

У вас есть пробел после строки "daysAllowed", поэтому значение daysAllowed равно нулю, поскольку в вашем json-файле нет подходящего ключа, соответствующего "daysAllowed", и любое последующее действие, которое вы выполняете, - это вызов get() on нулевой объект.

Я бы предложил, если еще нет, использовать подходящую IDE со средством отладки и построчно обойти код и посмотреть, что произойдет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...