Разбор JSON с JsonArray и HashMap - PullRequest
       1

Разбор JSON с JsonArray и HashMap

1 голос
/ 28 октября 2019

Мне нужно проанализировать следующий JSON и добавить значения из него в три разных объекта Java. Я думал сформировать 3 других Jsons, чтобы сделать это. У меня есть некоторые проблемы с синтаксическим анализом, поскольку JSON немного сложнее. Ниже приведен JSON:

{
 "totalCount": 1,
 "results": [
   {
     "teleCommunications": [
       {
         "areaCode": "100",
         "telephoneNumber": "300-2444",
         "internationalAreaCode": "",
         "communicationType": 1
       },
       {
         "areaCode": "100",
         "telephoneNumber": "200-2555",
         "internationalAreaCode": "",
         "communicationType": 5
       }
     ],
     "delegate": {
       "id": 0,
       "range": 0,
     },
     "name": "Andrew",
     "composedKey": {
       "id": 615,
       "range": 50,
     },
     "isBranchAddress": false,
     "emailAddresses": [
       {
         "emailAddressType": 9,
         "emailAddress": "andrew.brown@gmail.com"
       }
     ],
     "name": "Brown",
     "zipCodeCity": "65760 Leipzig",
     "salutation": "Mr.",
     "openingDate": "2019-09-20",
     "streetHouseNumber": "Offenbach. 37",
     "modificationTimestamp": "2018-01-27"
   }
 ]
}

Мне нужно отдельно получить значения из name, zipCodeCity, salutation, opensDate, streetHouseNumber в JSON (или любым другим способом), emailAddresses в другом JSON и других данных. в другом.

Я пробовал с этим фрагментом кода:

ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
HashMap<String, Object> result  = new ObjectMapper().readValue(response, HashMap.class);

Object object = result.get("results");


List<HashMap<String, String>> jsonValues = (List<HashMap<String, String>>)object;

     for(String key : jsonValues.get(0).keySet()){

         System.out.println("name value " + jsonValues.get(0).get("name"));
         System.out.println("zip code City " + jsonValues.get(0).get("zipCodeCity"));

    }

Проблема в том, что я бы не пошел таким жестко закодированным способом ... он не очень подходит. Кто-нибудь знает лучший подход для хранения нужных мне значений и более оптимального разбора Json?

Спасибо

Ответы [ 3 ]

1 голос
/ 28 октября 2019

Найдите эту ссылку, специально для вас есть демонстрационное приложение: https://github.com/nalmelune/jackson-demo-58591850 (посмотрите JacksonTest)

Прежде всего, вам понадобятся классы данных для этого (илитак называемый dto), представляющий структуру. Для этого вы можете использовать онлайн-генераторы (Google "JSON to Java Java Online") или сделать это самостоятельно. Например, вот корневой объект (см. Ссылку на github):

public class Root {
   private int totalCount;
   private List<Results> results;

   public void setTotalCount(int totalCount) {
       this.totalCount = totalCount;
   }

   public int getTotalCount() {
       return this.totalCount;
   }

   public void setResults(List<Results> results) {
       this.results = results;
   }

   public List<Results> getResults() {
       return this.results;
   }
}

Затем настройте свой ObjectMapper:

ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JavaTimeModule());
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

И используйте его (не создавайте новый картограф, так какв вашем примере):

Root result = mapper.readValue(response, Root.class);

Наконец, вы можете получить к нему доступ как к обычным простым Java-объектам:

    for (Results resultItem : result.getResults()) {
        System.out.println(resultItem.getSalutation());
        System.out.println(resultItem.getName());
        System.out.println(resultItem.getZipCodeCity());
        System.out.println(resultItem.getOpeningDate());
        System.out.println(resultItem.getStreetHouseNumber());
    }

Чтобы это работало, убедитесь, что подтвердили свой json (там были недействительныезапятые после «range» и «name» встречаются дважды и т. д., они исправлены на github). И обязательно включите jsr310 в classpath, добавив модуль com.fasterxml.jackson.datatype:jackson-datatype-jsr310. Он понадобится вам для LocalDate и LocalDateTime объектов.

0 голосов
/ 28 октября 2019

Ваш подход верен, поскольку вы просто читаете свой объект JSON как Map<String, Object>, который всегда будет работать (пока действует объект JSON). А затем вы получаете ваши значения, которые вы ожидаете там. Другой подход заключается в создании класса, который сопоставляется с вашим исходным JSON и анализирует JSON с ObjectMapper в вашем классе. Затем вы можете получить ваши данные с помощью ваших установщиков и получателей классов. В этом случае вам не нужно использовать ключевые строки, такие как «результаты» и т. Д., Но вы должны убедиться, что ваш JSON не только является допустимым JSON, но и всегда соответствует вашему классу. Выберите свой вариант ...

0 голосов
/ 28 октября 2019

Вы можете создать java-класс примерно так:

@Data
 class MyCustomClass{
    int totalCount;
    List<TeleCommunicationDetail> results;
   // other props
 }

Затем вы можете добавить атрибуты к TeleCommunicationDetail и, наконец, вы можете использовать MyCustomClass reaonseInJavaObject = objectMapper.readValue(myJson,MyCustomClass.class);

См. this вопрос для деталей.

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