第三方JSON解析兼容问题:RadarReport字段为对象或数组
兼容单个对象与数组的Gson解析方案
要解决第三方接口返回JSON中RadarReport字段时而为单个对象、时而为数组的解析问题,核心思路是给List<RadarReport>类型自定义TypeAdapter,让Gson自动适配两种格式。
步骤1:修正实体类
补充JSON中缺失的字段,统一将RadarReport声明为List类型:
@Data public class RadarReport { private String abc; private String name; private String id; private String ownerId; } @Data public class Radarreports { private String executionTime; // 补充JSON中的executionTime字段 private int size; private List<RadarReport> RadarReport; // 统一用List接收,兼容单对象/数组 } @Data public class ReportsResponse { private Radarreports RadarReports; }
步骤2:编写自定义TypeAdapter
实现一个通用适配器,处理单对象转List的逻辑:
public class SingleOrListTypeAdapter<T> extends TypeAdapter<List<T>> { private final TypeAdapter<T> itemAdapter; public SingleOrListTypeAdapter(Gson gson, Type itemType) { this.itemAdapter = gson.getAdapter(TypeToken.get(itemType)); } @Override public void write(JsonWriter out, List<T> value) throws IOException { // 序列化时,若List仅含一个元素,输出为单个对象;否则输出数组 if (value == null || value.isEmpty()) { out.nullValue(); return; } if (value.size() == 1) { itemAdapter.write(out, value.get(0)); } else { out.beginArray(); for (T item : value) { itemAdapter.write(out, item); } out.endArray(); } } @Override public List<T> read(JsonReader in) throws IOException { List<T> resultList = new ArrayList<>(); JsonToken token = in.peek(); if (token == JsonToken.BEGIN_OBJECT) { // 单个对象场景:解析后加入List T item = itemAdapter.read(in); resultList.add(item); } else if (token == JsonToken.BEGIN_ARRAY) { // 数组场景:逐个解析元素加入List in.beginArray(); while (in.hasNext()) { T item = itemAdapter.read(in); resultList.add(item); } in.endArray(); } return resultList; } }
步骤3:注册适配器并解析JSON
创建Gson实例时注册自定义适配器,即可兼容两种格式的解析:
URL url = new URL(queryUrl); BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream())); Gson gson = new GsonBuilder() // 为List<RadarReport>类型注册适配器 .registerTypeAdapter( new TypeToken<List<RadarReport>>() {}.getType(), new SingleOrListTypeAdapter<>(new Gson(), RadarReport.class) ) .create(); ReportsResponse radarReports = gson.fromJson(br, ReportsResponse.class);
说明
- 适配器会自动判断JSON中
RadarReport的类型:若为单个对象则包装成List;若为数组则直接解析为List。 - 原代码中的
RadarreportSet字段在提供的JSON示例中不存在,可直接删除以避免冗余。
内容的提问来源于stack exchange,提问作者sandy
相关产品推荐
相关产品推荐

