Сопоставьте JSON с несколькими неизвестными полями в Java POJO

Я пытаюсь сопоставить приведенный ниже JSON с Java POJO. Ниже приведен JSON.

{
  "customObject": {
    "value": {
      "config-1": {
        "configurationName": {
          "de": "Das ist ein Text",
          "en": "Hospitalization Cover"
        },
        "key": "hospitalization-cover",
        "mandatory": false,
        "type": "options",
        "options": {
          "1Lakh": {
            "label": "1 Lakh",
            "priceType": "fixed",
            "price": "200",
            "default": "true"
          },
          "2Lakh": {
            "label": "2 Lakh",
            "priceType": "fixed",
            "price": "400"
          },
          "3Lakh": {
            "label": "3 Lakh",
            "priceType": "fixed",
            "price": "450"
          },
          "4Lakh": {
            "label": "4 Lakh",
            "priceType": "fixed",
            "price": "500"
          },
          "5Lakh": {
            "label": "5 Lakh",
            "priceType": "fixed",
            "price": "550"
          },
          "6Lakh": {
            "label": "6 Lakh",
            "priceType": "fixed",
            "price": "650"
          },
          "7Lakh": {
            "label": "7 Lakh",
            "priceType": "fixed",
            "price": "780"
          }
        }
      },
      "config-2": {
        "configurationName": {
          "de": "Das ist ein Text",
          "en": "OPD Cover"
        },
        "key": "opd-cover",
        "mandatory": false,
        "type": "number",
        "options": {
          "OPDCover10k": {
            "label": "10,000",
            "priceType": "calculated",
            "priceFactor": 0.2,
            "default": "true"
          },
          "OPDCover15k": {
            "label": "15,000",
            "priceType": "calculated",
            "priceFactor": 0.27
          }
        }
      }
    }
  }
}

Я создал ниже POJO, чтобы сопоставить его.

package com.edu.epam.graphQLSearch.custom.graphlQLqueries;

public class GqCustomObject {

    private GqConfigCustomPOValue customObject;

    public GqConfigCustomPOValue getCustomObject() {
        return customObject;
    }

    public void setCustomObject(GqConfigCustomPOValue customObject) {
        this.customObject = customObject;
    }
}

Выше POJO работает нормально. Ниже приведен второй POJO.

package com.edu.epam.graphQLSearch.custom.graphlQLqueries;

public class GqConfigCustomPOValue {


    public GqCustomPOCAList value;

    public GqCustomPOCAList getValue() {
        return value;
    }

    public void setValue(GqCustomPOCAList value) {
        this.value = value;
    }
}

Ниже третий POJO

package com.edu.epam.graphQLSearch.custom.graphlQLqueries;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

import java.util.List;


public class GqCustomPOCAList {


    public List<GqCustomPOConfigAttributes> config;

    public List<GqCustomPOConfigAttributes> getConfig() {
        return config;
    }

    public void setConfig(List<GqCustomPOConfigAttributes> config) {
        this.config = config;
    }
}

Ниже четвертый POJO

package com.edu.epam.graphQLSearch.custom.graphlQLqueries;

public class GqCustomPOConfigAttributes {

    private String configurationName;
    private String key;
    private boolean mandatory;
    private String type;
    private Object options;

    public String getConfigurationName() {
        return configurationName;
    }

    public void setConfigurationName(String configurationName) {
        this.configurationName = configurationName;
    }

    public String getKey() {
        return key;
    }

    public void setKey(String key) {
        this.key = key;
    }

    public boolean isMandatory() {
        return mandatory;
    }

    public void setMandatory(boolean mandatory) {
        this.mandatory = mandatory;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public Object getOptions() {
        return options;
    }

    public void setOptions(Object options) {
        this.options = options;
    }
}

У меня возникла проблема с POJO GqCustomPOCAList. Здесь я не могу определить ключ «config-1», как он упоминается в JSON.

Когда я определяю это как public List<GqCustomPOConfigAttributes> config;, я получаю ошибку

Exception in thread "main" com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "config-1" (class com.edu.epam.graphQLSearch.custom.graphlQLqueries.GqCustomPOCAList), not marked as ignorable (one known property: "config"])
 at [Source: (String)"{"customObject":{"value":{"config-1":{"configurationName":{"de":"Das ist ein Text","en":"Hospitalization Cover"},"key":"hospitalization-cover","mandatory":false,"type":"options","options":{"1Lakh":{"label":"1 Lakh","priceType":"fixed","price":"200","default":"true"},"2Lakh":{"label":"2 Lakh","priceType":"fixed","price":"400"},"3Lakh":{"label":"3 Lakh","priceType":"fixed","price":"450"},"4Lakh":{"label":"4 Lakh","priceType":"fixed","price":"500"},"5Lakh":{"label":"5 Lakh","priceType":"fixed","pri"[truncated 447 chars]; line: 1, column: 39] (through reference chain: com.edu.epam.graphQLSearch.custom.graphlQLqueries.GqCustomObject["customObject"]->com.edu.epam.graphQLSearch.custom.graphlQLqueries.GqConfigCustomPOValue["value"]->com.edu.epam.graphQLSearch.custom.graphlQLqueries.GqCustomPOCAList["config-1"])
    at com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:61)

Я не могу определить переменную, как показано ниже, в классе Java

public List<GqCustomPOConfigAttributes> config-1;

Есть ли лучший способ справиться с этим?

Иногда лучше просто использовать класс JsonNode, а не POJO. Например, что делать, если существует более двух значений конфигурации? Здесь нет списков JSON, поэтому список массивов недействителен.

OneCricketeer 15.04.2024 17:47

Вы можете использовать @JsonProperty("config-1")

Wladimir Diskowski 15.04.2024 17:53

Ваша структура json не соответствует структуре вашего объекта. Есть ли у вас доступ для изменения JSON?

tbatch 15.04.2024 18:23
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
2
3
66
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Если у вас есть несколько неизвестных полей, лучший способ их проанализировать — использовать аннотацию @JsonAnySetter. Эта аннотация позволяет вам добавить неизвестную пару ключ-значение в определенное поле по вашему выбору (обычно Map).

Вот рабочая демонстрация синтаксического анализа вашего json в OneCompiler.

Вот список предложений/исправлений в вашем коде:

class GqCustomPOCAList {

    // 1. Do not use a List to parse an unknown number of configs,
    // use instead the @JsonAnyGetter annotation and a Map to add every config with their name as the key (config-1, config-2, etc.)
    public Map<String, GqCustomPOConfigAttributes> config;

    // 2. initializing the Map so that it can be used by the method marked with @JsonAnySetter
    public GqCustomPOCAList(){
        config = new HashMap<>();
    }

    // 3. Method to add a generic config to the Map
    @JsonAnySetter
    public void addConfig(String cofigName, GqCustomPOConfigAttributes value){
        config.put(cofigName, value);
    }

    //... other methods ...
}
class GqCustomPOConfigAttributes {

    // 4. configurationName appears to be a Map<String, String> within your Json, not a String
    private Map<String, String> configurationName;
    private String key;
    private boolean mandatory;
    private String type;

    // 5. Do not use a generic Object to represent your option, define a class Option with the possible fields.
    // 6. Again, if the possible options are unknown, use a Map<String, Option> and the @JsonAnySetter annotation
    private Map<String, Option> options;

    // 7. initializing the Map so that it can be used by the method marked with @JsonAnySetter
    public GqCustomPOConfigAttributes(){
        configurationName = new HashMap<>();    
    }

    // 8. Method to add a generic option to the Map
    @JsonAnySetter
    public void addOption(String optionName, Option option){
        options.put(optionName, option);
    }

    // ... other methods ...
}
class Option {
    private String label;
    private String priceType;
    private BigDecimal price;
    private BigDecimal priceFactor;

    // 9. the 'default' property must be renamed as default is a java keyword,
    // use @JsonProperty to bind it to the field 'default' within the Json
    @JsonProperty("default")
    private boolean isDefault;

    // ... other methods ...
}

Другие вопросы по теме