Сохраняйте тип при преобразовании объекта в карту - PullRequest
1 голос
/ 26 сентября 2019

версия Джексона: 2.9.8

Я конвертирую объект не в JSON, а в Карту, используя objectMapper.convertValue(myObject, Map.class)

Вот простой пример для воспроизведения.My Pojo:

public static class Foo {
    private final String string;
    private final LocalDate date;
    public Foo(String string, LocalDate date) {
        this.string = string;
        this.date = date;
    }
    public String getString() {
        return string;
    }
    public LocalDate getDate() {
        return date;
    }
}

Код преобразования:

public static void main(String[] args) {
    Foo foo = new Foo("hello", LocalDate.of(1999, 12, 31));

    ObjectMapper objectMapper = new ObjectMapper();
    Map map = objectMapper.convertValue(foo, Map.class);

    Object string = map.get("string");
    System.out.println("string: >>>"+ string +"<<< of type "+ string.getClass().getName());

    Object date = map.get("date");
    System.out.println("date: >>>"+ date +"<<< of type "+ date.getClass().getName());
}

Печатается:

string: >>>hello<<< of type java.lang.String
date: >>>{year=1999, month=DECEMBER, chronology={id=ISO, calendarType=iso8601}, era=CE, dayOfMonth=31, dayOfWeek=FRIDAY, dayOfYear=365, leapYear=false, monthValue=12}<<< of type java.util.LinkedHashMap

При включении модуля JavaTimeModule с

objectMapper.registerModule(new JavaTimeModule());

он печатает:

string: >>>hello<<< of type java.lang.String
date: >>>[1999, 12, 31]<<< of type java.util.ArrayList

Но мне нужно, чтобы сохранить экземпляр LocalDate на карте.Нет конверсии.Я не могу найти, как настроить Джексона для сохранения (не преобразования) типа.

Я пытался с помощью noop-конвертера:

private static class KeepLocalDateJsonSerializer extends JsonSerializer<LocalDate> {
    @Override
    public void serialize(LocalDate localDate, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
        jsonGenerator.writeObject(localDate);
    }
};

, регистрируя его с помощью

    SimpleModule mod = new SimpleModule("KeepLocalDate");
    mod.addSerializer(LocalDate.class, new KeepLocalDateJsonSerializer());
    objectMapper.registerModule(mod);

и это приводит к ошибке StackOverflowError с деталями:

ReadOnlyClassToSerializerMap.typedValueSerializer(ReadOnlyClassToSerializerMap.java:85)
JsonMappingException: Infinite recursion $Foo["date"]

Очевидно, Джексон также пытается преобразовать возвращаемое значение.Похоже, ошибка для меня.Если преобразователь записывает один и тот же объект, даже один и тот же экземпляр, то очевидно, что цель состоит в том, чтобы сохранить его.При преобразовании в JSON я понимаю, что мы не можем сохранить экземпляр LocalDate, но в Map это не так.

Как можно добиться этого общим способом, чтобы он работал для любой структуры данных?Без аннотации в Пойо.Таким образом, все экземпляры определенного типа данных пропускаются через нетронутыми.

Есть похожий вопрос Преобразование объекта Джексона в карту с сохранением типа даты , но ему 5 лет, используется Date not LocalDate,и решение с SerializationFeature.WRITE_DATES_AS_TIMESTAMPS здесь не работает.

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