Как де/сериализовать List‹Object› с Джексоном?

Как сериализовать/десериализовать список объектов, как показано ниже, с помощью Джексона?

List<Object> items = new ArrayList<Object>();
items.add(1);           //integer
items.add(1.23);        //float
items.add("abc");       //string
items.add(Color.RED);   //enum
items.add(new Date());  //date

Возможные классы элементов: integer, float, string, enum и date. Базовым классом элементов является объект, поэтому нет возможности указать @JsonTypeInfo.

Желаемый вывод должен быть похож на вывод @JsonTypeInfo, например,

[
{"java.lang.Integer": 1},
{"java.lang.Float": 1.23},
{"java.lang.String": "abc"},
{"mypackage.Color": "RED"},
{"java.util.Date","2000-01-01T00:00:00+0000"}
]

Or

[
    {type:"java.lang.Integer",value: 1},
    {type:"java.lang.Float",value: 1.23},
    ...
]

Может быть, мне нужен MixIn, чтобы настроить это самостоятельно?


person Leon    schedule 01.02.2016    source источник
comment
Пожалуйста, включите желаемый сериализованный вывод в свой пост.   -  person Bnrdo    schedule 01.02.2016


Ответы (1)


Вы не можете сделать это с JsonTypeInfo. Вам нужен собственный сериализатор, который проверяет экземпляр каждого элемента в списке и соответствующим образом сериализует их.

Сначала создайте оболочку вашего списка.

@JsonSerialize(using = MyCustomListSerializer.class)
public class ListWrapper {
    private List<Object> list;

    public ListWrapper(){
        list = new ArrayList<>();
    }

    public void add(Object o){
        list.add(o);
    }

    public Object get(int i){
        return list.get(i);
    }

    public List<Object> list(){
        return list;
    }
}

Затем пользовательский сериализатор

public class MyCustomListSerializer extends JsonSerializer<ListWrapper> {
    @Override
    public void serialize(ListWrapper value, JsonGenerator jgen, SerializerProvider provider)
      throws IOException, JsonProcessingException {

        jgen.writeStartArray();

        for(Object o : value.list()){
            jgen.writeStartObject();
            if(o instanceof Integer){
                jgen.writeNumberField("java.lang.Integer", (int) o);
            }else if(o instanceof Double){ //by default, floated values are represented by double
                jgen.writeNumberField("java.lang.Float", (double) o);
            }else if(o instanceof Color){
                jgen.writeStringField("myPackage.Color", ((Color)o).toString());
            }else if(o instanceof Date){
                jgen.writeStringField("java.util.Date", o.toString());
            }else{ //default to String
                jgen.writeStringField("java.lang.String", o.toString());
            }
            jgen.writeEndObject();
        }

        jgen.writeEndArray();
    }
}
person Bnrdo    schedule 02.02.2016
comment
Да, спасибо. Поскольку список объектов находится в некоторых других классах, я бы добавил миксины для использования пользовательского де/сериализатора. - person Leon; 02.02.2016