我的JSON结构:
{
...
"type":"post", // Type could vary
"items":[] // Array of items, each item is typeOf("type")
...
}
如何在我的POJO中反序列化并正确包裹items
列表:
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
}
要包裹类型列表,应提供CREATOR
对象,显然,界面无法提供。
我应该使用抽象类而不是接口吗?
答案 0 :(得分:0)
First things first: EXTERNAL_PROPERTY
will only work when value is enclosed within another Object (POJO); and will not work for List
s, arrays or Map
s.
If you were using one of other inclusion method, things should work in that you can serialize content as JSON, and read produced JSON back retaining types as expected. That is, round-trip serialization is supported when starting with Java objects. Beyond this, some JSON encoding structures can be supported; but it depends on exact kind of structure you are trying to support.
答案 1 :(得分:0)
好吧,因为杰克逊期望每个列表元素的类型信息,我不想写这个POJO的自定义反序列化器 - 我用另一种方式解决了。
首先,我做了一个所有子类项目必须实现的接口。
@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();
// ...
}
然后我创建了一个基类,我的所有子类项都必须扩展。
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;
}
// ...
}
最后,我的POJO课程:
public class NewsFeedEnvelope {
// ...
@JsonProperty("rows")
private List<FeedItem> items;
// ...
}
现在,POJO已成功自动反序列化,没有任何自定义反序列化器。