Jackson robi coś naprawdę dziwnego i nie mogę znaleźć żadnego wyjaśnienia. Robię serializację polimorficzną i działa doskonale, gdy obiekt jest sam. Ale jeśli umieścisz ten sam obiekt na liście i zamiast niego zmienisz katalog, usunie on informacje o typie.Dlaczego serializacja polimorficzna Jacksona nie działa na listach?
Fakt, że traci informacje o typie, może spowodować podejrzenie, że typ został usunięty. Ale dzieje się to podczas serializacji zawartości listy; wszystko, co Jackson musi zrobić, to sprawdzenie aktualnego obiektu, który serializuje, aby określić jego typ.
Utworzyłem przykład używając Jackson 2.5.1:
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonSubTypes.Type;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.JsonTypeName;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.ArrayList;
import java.util.List;
public class Test {
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY)
@JsonSubTypes({
@Type(value = Dog.class, name = "dog"),
@Type(value = Cat.class, name = "cat")})
public interface Animal {}
@JsonTypeName("dog")
public static class Dog implements Animal {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
@JsonTypeName("cat")
public static class Cat implements Animal {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public static void main(String[] args) throws JsonProcessingException {
List<Cat> list = new ArrayList<>();
list.add(new Cat());
System.out.println(new ObjectMapper().writeValueAsString(list));
System.out.println(new ObjectMapper().writeValueAsString(list.get(0)));
}
}
Oto wynik:
[{"name":null}]
{"@type":"cat","name":null}
Jak widać, Jackson nie jest dodanie informacji o typie gdy obiekt jest na liście. Czy ktoś wie, dlaczego tak się dzieje?
Również można użyć jak 'nowej ObjectMapper() writerFor (mapper.getTypeFactory() constructCollectionType (List.class, zwierząt.. klasa)). writeValueAsString (lista) ' –
To jest naprawdę dziwne i nie mogę sobie wyobrazić, dlaczego mieliby dokonać takiego wyboru. Niezależnie od rodzaju listy, można by sądzić, że obiekty, które są w niej zawarte, będą serializowane w ten sam sposób przez cały czas. – monitorjbl
mapper.writerWithType (mapper.getTypeFactory(). ConstructCollectionType (List.class, Animal.class)). WriteValueAsString (lista) – Youness