Jackson sta facendo qualcosa di veramente bizzarro e non riesco a trovare alcuna spiegazione per questo. Sto facendo serializzazione polimorfica e funziona perfettamente quando un oggetto è da solo. Ma se metti lo stesso oggetto in una lista e serializzi la lista, cancella le informazioni sul tipo.Perché la serializzazione polimorfa di Jackson non funziona negli elenchi?
Il fatto che stia perdendo informazioni sul tipo porterebbe a sospettare la cancellazione del tipo. Ma questo sta accadendo durante la serializzazione del contenuto della lista; tutto ciò che Jackson deve fare è ispezionare l'oggetto corrente che sta serializzando per determinare il suo tipo.
ho creato un esempio utilizzando 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)));
}
}
ecco l'output:
[{"name":null}]
{"@type":"cat","name":null}
Come si può vedere, Jackson non aggiunge le informazioni sul tipo quando l'oggetto è in una lista. Qualcuno sa perché questo sta accadendo?
Inoltre è possibile utilizzare come 'nuova ObjectMapper() writerFor (mapper.getTypeFactory() constructCollectionType (List.class, Animale.. class)). writeValueAsString (list) ' –
Questo è davvero strano, e non riesco a immaginare perché avrebbero fatto quella scelta. Indipendentemente dal tipo di elenco, penseresti che gli oggetti al suo interno vengano serializzati nello stesso modo in ogni momento. – monitorjbl
mapper.writerWithType (mapper.getTypeFactory(). ConstructCollectionType (List.class, Animal.class)). WriteValueAsString (elenco) – Youness