Сериализация Джексона игнорирует '@JsonTypeInfo' и '@JsonIgnore' для классов итераторов? - PullRequest
1 голос
/ 16 марта 2020

Я недавно обновился с Jackson 2.9.10 до 2.10.0 и заметил изменение в том, как классы Iterator сериализуются.

Учитывая приведенный ниже тест, вывод с 2.9.10 (с обработкой JsonTypeInfo и JsonIgnore) будет

{"@ class": "IteratorTest"}

, но с 2.10.0, JsontTypeInfo и JsonIgnore не обрабатываются и выводятся

["IteratorTest", ["one", "two"]]

Правильно ли новое поведение сериализации? Есть ли способ обойти старое поведение?

// Test class
import java.util.Iterator;
import java.util.ArrayList;
import java.util.List;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.IOException;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonTypeInfo;

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "@class", visible=true)
public class IteratorTest<T> implements Iterator<T> {
    @JsonIgnore 
    private Iterator<T> iterData;
    private static final ObjectMapper MAPPER = new ObjectMapper();
    IteratorTest(Iterator<T> iterData) { this.iterData = iterData; }

    @Override 
    public boolean hasNext() {
        return iterData.hasNext();
    }
    @Override
    public T next() {
        return iterData.next();
    }

    public static void main(String[] args) throws IOException {
        List<String> strings = new ArrayList<>();
        strings.add("one");
        strings.add("two");

        IteratorTest<String> it = new IteratorTest<>(strings.iterator());

        System.out.println("-- serializing --");
        String s = MAPPER.writeValueAsString(it);
        System.out.println(s);
    }
}
// end of Test class

1 Ответ

0 голосов
/ 16 марта 2020

Да, отладка, с версией 2.9.10 вы получаете BeanSerializer, с версией 2.10.0 вы получаете IteratorSerializer.

В версии 2.10.0 вы получаете IteratorSerializer когда у вашего класса нет свойств (BeanSerializerFactory.findSerializerByAddonType). В версии 2.9.10 вы получаете BeanSerializer от builder.createDummy().

Исправление:

  • Использование собственного сериализатора
  • может изменить обработку Итератора -Классы для вашего OM
  • Использовать существующее свойство, st BeanSerializer создано (это даст вам другое json):

    @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "myClass")
    class IteratorTest<T> implements Iterator<T> {
    
        private String myClass = IteratorTest.class.getSimpleName();
    
        ...
    }
    
...