2013-05-10 10 views
10

Korzystanie z spin na przykład zoo:Jackson Polimorficzne Deserializacja - Czy możesz wymagać istnienia pola zamiast określonej wartości?

public class ZooPen { 
    public String type; 
    public List<Animal> animals; 
} 

public class Animal { 
    public String name; 
    public int age; 
} 

public class Bird extends Animal { 
    public double wingspan; 
} 

chcę użyć polimorficzny deserializacji skonstruować instancje zwierząt, jeżeli nie jest określona rozpiętość skrzydeł, a przypadki ptaków, jeżeli jest. W Jackson, bez typu deserializacji zazwyczaj wygląda mniej więcej tak:

@JsonTypeInfo( 
    use = JsonTypeInfo.Id.NAME, 
    include = JsonTypeInfo.As.PROPERTY, 
    property = "wingspan", 
    visible = true, 
    defaultImpl = Animal.class 
) 
@JsonSubTypes({ 
    @Type(value = Bird.class, name = **???**) 
}) 
public class Animal { 
    ... 
} 

Wartość rozpiętość skrzydeł może być wszystko, a bez tego dopasowania czegoś konkretnie Jackson wraca na klasie defaultImpl.

mogłem prawdopodobnie użyć @JsonCreator

@JsonCreator 
public static Animal create(Map<String,Object> jsonMap) 
     throws JsonProcessingException { 

    ObjectMapper mapper = new ObjectMapper(); 
    if (jsonMap.get("wingspan") == null) { 
     // Construct and return animal 
    } else { 
     // Construct and return bird 
    } 
} 

Jednak to muszę ręcznie obsługiwać dodatkowe wartości spójnych i rzucać wyjątki, i to nie jest jasne, czy Animal będzie w odcinkach odpowiednio później.

Czy istnieje sposób na zrobienie tego, co chcę, z obsługą polimorficznych typów? Wygląda na to, że mogę użyć własnego TypeResolver lub TypeIdResolver, ale wydaje się, że to więcej pracy niż deserializacja surowego json'a. Ewentualnie może istnieć sposób kierowania na typ pióra zoo, nawet jeśli znajduje się on w obiekcie nadrzędnym. Jakieś pomysły?

Edit:
TypeResolver i TypeIdResolver zdaje się zakładać, że wewnętrznie typ informacji jest seryjny, więc to nie są dobre do wykorzystania. Czy byłoby możliwe zaimplementowanie własnego JsonDeserializera, który przechwyciłby cykl życia w celu określenia typu, ale nadal używa podstawowej funkcji przetwarzania adnotacji jackson? Spoglądam na JsonDeserializer.deserializeWithType(...), ale wydaje się, że przeniesienie deserializacji całkowicie do TypeDeserializer. Istnieje również problem, który wymagałby deserializacji niektórych obiektów, zanim dowiem się, jakiego typu użyć.

+3

Czy kiedykolwiek znalazłeś sposób na osiągnięcie tego? Mam podobny problem, ale z wieloma podklasami typu "Bird", z których każdy ma określone pole, którego obecność identyfikuje tę podklasę. –

Odpowiedz

0

Jeśli nie jesteś w związku małżeńskim z Jacksonem, wierzę, że coś podobnego do tego można osiągnąć za pomocą FlexJSON.

http://flexjson.sourceforge.net/javadoc/flexjson/JSONDeserializer.html

jestem zaznajomiony z metodami Jacksona dla robią podobne rzeczy, ale mogę powiedzieć, że jest bardzo wydajnych FlexJSON iw ogóle intuicyjny w obsłudze podczas etapów serializacji/deserialziation.

Powiązane problemy