注意:这可以通过创建2个不同的GSON模型轻松实现,但我正在寻找解决方法。
我有一个可以处理多个JSON响应的模型。但是有一个回应:
items: [
{
kind: "youtube#playlistItem",
etag: ""fpJ9onbY0Rl_LqYLG6rOCJ9h9N8/jqbcTLu8tYm8b1FXGO14gNZrFG4"",
id: "PLUQ7I1jJqKB4lJarGcpWsP62l7iC06IkE2LDE0BxLe18",
与此相冲突(请注意具有不同类型的相同id
字段。上述id
为String
,另一个为Class
):
items: [
{
kind: "youtube#searchResult",
etag: ""fpJ9onbY0Rl_LqYLG6rOCJ9h9N8/hDIU49vmD5aPhKUN5Yz9gtljG9A"",
id: {
kind: "youtube#playlist",
playlistId: "PLh6xqIvLQJSf3ynKVEc1axUb1dQwvGWfO"
},
是否可以只使用一个可以读取这两个响应的GSON模型?
非常感谢你的时间
更新
这是在Model
内,我将id
变量从String
更改为Class
:
private Id id;
public class Id
{
private String id;
private String kind;
private String playlistId;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getKind() {
return kind;
}
public void setKind(String kind) {
this.kind = kind;
}
public String getPlaylistId() {
return playlistId;
}
public void setPlaylistId(String playlistId) {
this.playlistId = playlistId;
}
}
这就是我的请求:
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(Response.class,
new JsonDeserializer<Item.Id>() {
@Override
public Item.Id deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
if(jsonElement.isJsonObject())
{
result.setKind(jsonElement.getAsJsonObject().get("kind").getAsString());
result.setPlaylistId(jsonElement.getAsJsonObject().get("playlistId").getAsString());
//return new Item.Id(jsonElement.getAsJsonObject().get("kind").getAsString(), jsonElement.getAsJsonObject().get("playlistId").getAsString());
return result;
}
else
{
result.setId(jsonElement.getAsString());
//return new Item.Id(jsonElement.getAsString());
return result;
}
}
});
答案 0 :(得分:2)
问题
你只能有id表示单一类型的变量,在这种情况下,在第一个响应中你有字符串,在第二种情况下,你有一个对象,它有一个&#34; kind& #34;和一个&#34; playlistId&#34;
这似乎是后端方面的一个奇怪的设计,但它可能不在你的控制之下
<强>解决方案强>
你可以做的是如果你认为第一个和第二个响应中的id是相同类型的,你可以创建一个包含这些字段的封装类,如
class Id {
private String stringId;
private String kind;
private String playlistId;
}
并创建一个自定义JsonDeserializer,它将基于JSON响应的类型以下列方式创建相应的Id对象:
new JsonDeserializer<Id>() {
@Override
public Id deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
if(json.isJsonObject()) {
return new Id(json.getAsJsonObject().get("kind").getAsString(), json.getAsJsonObject().get("playlistId").getAsString());
} else {
return new Id(json.getAsString());
}
}
}
并在你的gson对象上注册它,因此它将处理Id字段的反序列化,并根据其类型库创建
或者你可以创建一个反序列化器来反序列化包含的对象,并根据id的类型使用不同的字段,但你应该明白这个想法!
您可以使用GsonBuilder在Gson上注册您的JsonDeserializer,并在GsonBuilder中调用registerTypeAdapter,其类型是您在以下方式注册类型适配器并使用typeadapter:
return new GsonBuilder().registerTypeAdapter(Id.class, new JsonDeserializer<Id>() {
//..
}).build();
您可以在gson文档中了解有关自定义类型适配器的更多信息,here!