2015-07-26 13 views
12

Moja struktura JSON:JsonSubTypes, lista polymorpic obiektów i Parcelable

{ 
    ... 
    "type":"post", // Type could vary 
    "items":[]  // Array of items, each item is typeOf("type") 
    ... 
} 

Jak mogę deserializowania i prawidłowo Parcel items listy wewnątrz mojego POJO:

public class ItemsEnvelope { 
    private String type; 

    @JsonTypeInfo(
      use = JsonTypeInfo.Id.NAME, 
      include = JsonTypeInfo.As.EXTERNAL_PROPERTY, 
      property = "type", 
      visible = true) 
    @JsonSubTypes({ 
      @JsonSubTypes.Type(value = A.class, name = "A"), 
      @JsonSubTypes.Type(value = B.class, name = "B"), 
      @JsonSubTypes.Type(value = C.class, name = "C") 
    }) 
    private List<Item> items; 

    interface Item extends Parcelable {} 

    class A implements Item { 
     // Bunch of getters/setters and Parcelable methods/constructor 
    } 

    class B implements Item { 
     // Bunch of getters/setters and Parcelable methods/constructor 
    } 

    class C implements Item { 
     // Bunch of getters/setters and Parcelable methods/constructor 
    } 

    // Bunch of getters/setters and Parcelable methods/constructor 
} 

Aby Parcel wpisywanych z wykazu CREATOR obiekt powinien być zapewnione, czego interfejs oczywiście nie może mieć. Czy powinienem używać klasy abstrakcyjnej zamiast interfejsu?

Odpowiedz

0

Cóż, ponieważ Jackson oczekuje informacji o typie na każdym elemencie listy i nie chciałem pisać niestandardowego deserializatora dla tego POJO - i rozwiązałem go w inny sposób.

Przede wszystkim zrobiłem interfejs, który musiałem wdrożyć wszystkie moje podtypy.

@JsonTypeInfo(
     use = JsonTypeInfo.Id.NAME, 
     include = JsonTypeInfo.As.EXTERNAL_PROPERTY, 
     property = "type", 
     visible = true) 
@JsonSubTypes({ 
     @JsonSubTypes.Type(value = PostFeedItem.class, name = BaseFeedItem.TYPE_POST), 
     @JsonSubTypes.Type(value = PhotoFeedItem.class, name = BaseFeedItem.TYPE_PHOTO), 
     @JsonSubTypes.Type(value = AudioFeedItem.class, name = BaseFeedItem.TYPE_AUDIO), 
     @JsonSubTypes.Type(value = VideoFeedItem.class, name = BaseFeedItem.TYPE_VIDEO), 
     @JsonSubTypes.Type(value = FriendFeedItem.class, name = BaseFeedItem.TYPE_FRIEND) 
}) 
public interface FeedItem extends Parcelable { 
    // ... 
    @BaseFeedItem.Type 
    String getType(); 
    // ... 
} 

Potem stworzyłem klasę bazową, której wszystkie elementy podtytułów musiały przedłużyć.

public abstract class BaseFeedItem implements FeedItem { 
    public static final String TYPE_POST = "post"; 
    public static final String TYPE_COMMUNITY_POST = "group_post"; 
    public static final String TYPE_PHOTO = "photo"; 
    public static final String TYPE_AUDIO = "audio"; 
    public static final String TYPE_VIDEO = "video"; 
    public static final String TYPE_FRIEND = "friend"; 

    @Retention(RetentionPolicy.SOURCE) 
    @StringDef({TYPE_POST, TYPE_COMMUNITY_POST, TYPE_PHOTO, TYPE_AUDIO, TYPE_VIDEO, TYPE_FRIEND}) 
    public @interface Type {} 
    private String type; 

    @Type 
    public String getType() { 
     return type; 
    } 
    // ... 
} 

Wreszcie moja klasa POJO:

public class NewsFeedEnvelope { 
    // ... 
    @JsonProperty("rows") 
    private List<FeedItem> items; 
    // ... 
} 

Teraz POJO powodzeniem automatycznie rozszeregować Jackson bez jakichkolwiek niestandardowych deserializers.

0

Po pierwsze: EXTERNAL_PROPERTY będzie działać tylko wtedy, gdy wartość jest zawarta w innym obiekcie (POJO); i nie będzie działać dla s, tablic ani Map s

Jeśli korzystasz z jednej z innych metod włączania, rzeczy powinny działać w taki sposób, że możesz serializować zawartość jako JSON i czytać wyprodukowane pliki JSON z powrotem, zgodnie z oczekiwaniami. Oznacza to, że serializacja w obie strony jest obsługiwana podczas uruchamiania z obiektami Java. Poza tym niektóre struktury kodowania JSON mogą być obsługiwane; ale zależy to od rodzaju struktury, którą próbujesz wspierać.

+0

Dodano strukturę json do pytania. Jaką metodę integracji powinienem zastosować w moim przypadku? – localhost

+0

Nie ma możliwości wskazania typów wszystkich elementów tablicy JSON; Jackson oczekuje informacji o typie każdego elementu. Aby wesprzeć tę aranżację, musisz napisać niestandardowy deserializator (i serializator, jeśli chcesz produkować taki JSON). – StaxMan

Powiązane problemy