Джексон десериализует JSON с помощью дженериков - PullRequest
0 голосов
/ 05 июля 2018

У меня есть некоторые проблемы с десериализацией полиморфной (полиморфной?) С Джексоном.

Предположим, у меня есть следующая структура JSON

{
  "list": [
    "02/01/2018",
    "03/01/2018",
    "04/01/2018",
    "05/01/2018",
    "08/01/2018",
    "05/02/2018"
  ]
}

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

public class GeneralResponseList<T> extends BaseResponse {

    @JsonProperty("list")
    private List<T> list;

    @JsonProperty("paging")
    private Paging paging;

    @JsonProperty("sorting")
    private List<Sorting> sorting;

    // [CUT]
}

Как указать десериализатор для типа T? Я смотрел на полиморфную десериализацию, но думаю, что это не решает мою проблему.

Я также могу создать определенный LocalDateResponseList, который расширяет GeneralResponseList<LocalDate>. Как указать десериализатор для конкретного ответа?

Можете ли вы предложить мне решение или подсказки для решения этой проблемы.

1 Ответ

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

Предполагая, что у вас есть такой класс:

public class GeneralResponseList<T> {

    @JsonProperty("list")
    private List<T> list;

    // Getters and setters
}

Вы можете использовать TypeReference<T>:

GeneralResponseList<LocalDate> response = 
    mapper.readValue(json, new TypeReference<GeneralResponseList<LocalDate>>() {});

Если у вас несколько форматов даты, как вы упомянули в комментариях, вы можете написать собственный десериализатор для обработки:

public class LocalDateDeserializer extends StdDeserializer<LocalDate> {

    private List<DateTimeFormatter> availableFormatters = new ArrayList<>();

    protected LocalDateDeserializer() {
        super(LocalDate.class);
        availableFormatters.add(DateTimeFormatter.ofPattern("dd/MM/yyyy"));
        availableFormatters.add(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
    }

    @Override
    public LocalDate deserialize(JsonParser p, DeserializationContext ctxt) 
            throws IOException {

        String value = p.getText();

        if (value == null) {
            return null;
        }

        for (DateTimeFormatter formatter : availableFormatters) {
            try {
                return LocalDate.parse(value, formatter);
            } catch (DateTimeParseException e) {
                // Safe to ignore
            }
        }

        throw ctxt.weirdStringException(value, LocalDate.class, "Unknown date format");
    }
}

Затем добавьте десериализатор в модуль и зарегистрируйте Module в ObjectMapper экземпляре:

ObjectMapper mapper = new ObjectMapper();

SimpleModule module = new SimpleModule();
module.addDeserializer(LocalDate.class, new LocalDateDeserializer());
mapper.registerModule(module);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...