Android Gson解析同key对应Boolean/ArrayList时POJO处理方案问询
错误原因
该异常是由于后端返回的JSON结构不规范导致:同一tags字段存在两种数据类型,部分节点返回布尔值,部分节点返回标签数组,Gson默认反序列化逻辑无法自动兼容多类型的同名字段。
解决方案
通过自定义Gson类型适配器兼容两种类型的解析即可,步骤如下:
1. 自定义tags字段的TypeAdapter
import com.google.gson.TypeAdapter; import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonToken; import com.google.gson.stream.JsonWriter; import java.io.IOException; import java.util.ArrayList; public class TagsTypeAdapter extends TypeAdapter<ArrayList<WebTags>> { @Override public void write(JsonWriter out, ArrayList<WebTags> value) throws IOException { // 序列化逻辑,无序列化需求可直接保留默认实现 if (value == null || value.isEmpty()) { out.value(false); return; } out.beginArray(); for (WebTags tag : value) { out.beginObject(); out.name("term_id").value(tag.getTerm_id()); out.name("name").value(tag.getName()); out.endObject(); } out.endArray(); } @Override public ArrayList<WebTags> read(JsonReader in) throws IOException { ArrayList<WebTags> tagsList = new ArrayList<>(); JsonToken peek = in.peek(); // 处理布尔类型的tags if (peek == JsonToken.BOOLEAN) { in.nextBoolean(); return tagsList; // 处理数组类型的tags } else if (peek == JsonToken.BEGIN_ARRAY) { in.beginArray(); while (in.hasNext()) { WebTags tag = new WebTags(); in.beginObject(); while (in.hasNext()) { String name = in.nextName(); if ("term_id".equals(name)) { tag.setTerm_id(in.nextString()); } else if ("name".equals(name)) { tag.setName(in.nextString()); } else { in.skipValue(); } } in.endObject(); tagsList.add(tag); } in.endArray(); return tagsList; } in.skipValue(); return tagsList; } }
2. 注册适配器
有两种注册方式可选:
方式1:全局注册(对所有ArrayList类型字段生效)
Gson gson = new GsonBuilder() .registerTypeAdapter(new TypeToken<ArrayList<WebTags>>(){}.getType(), new TagsTypeAdapter()) .create(); // 后续使用该自定义gson实例解析JSON即可 List<Posts> postsList = gson.fromJson(待解析的JSON字符串, new TypeToken<List<Posts>>(){}.getType());
方式2:字段单独注册(仅对当前Posts类的tags字段生效,更推荐)
直接在Posts类的tags字段上添加@JsonAdapter注解,无需修改Gson实例配置:
public class Posts implements Serializable { String id; String title; boolean mIsBookmark; String date; // 注意补全你当前代码缺失的date成员变量,否则会编译报错 @JsonAdapter(TagsTypeAdapter.class) ArrayList<WebTags> tags; // 原有get/set方法保持不变即可 }
补充说明
如果业务逻辑中布尔值true有特殊含义,可自行修改TagsTypeAdapter中read方法的处理逻辑,比如返回预置的默认标签列表即可。
内容的提问来源于stack exchange,提问作者Sunil
相关产品推荐
相关产品推荐

