如何实现泛型Data类兼容JSON中data节点的数组与对象?
解决方案
1. 定义泛型Data类
先统一泛型结构,将data字段定义为集合类型,确保两种JSON格式最终都能解析为统一的实体集合:
public class Data<T> { private int code; private String message; private List<T> data; // 构造器、getter、setter方法按需实现 }
2. 自定义泛型TypeAdapterFactory
创建适配器工厂,自动识别并处理单个对象/数组的兼容解析,同时支持泛型适配不同实体类(如Client、Provider):
import com.google.gson.*; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.List; public class SingleOrArrayTypeAdapterFactory implements TypeAdapterFactory { @SuppressWarnings("unchecked") @Override public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) { // 仅处理List类型字段 if (!List.class.isAssignableFrom(type.getRawType())) { return null; } // 获取List的泛型参数类型(如Client、Provider) Type elementType = ((ParameterizedType) type.getType()).getActualTypeArguments()[0]; TypeAdapter<?> elementAdapter = gson.getAdapter(TypeToken.get(elementType)); return (TypeAdapter<T>) new TypeAdapter<List<?>>() { @Override public void write(JsonWriter out, List<?> value) throws IOException { // 序列化逻辑:列表仅1个元素时输出为单个对象,否则输出数组(按需可调整为始终输出数组) if (value.size() == 1) { elementAdapter.write(out, value.get(0)); } else { out.beginArray(); for (Object item : value) { elementAdapter.write(out, item); } out.endArray(); } } @Override public List<?> read(JsonReader in) throws IOException { List<Object> resultList = new ArrayList<>(); JsonToken token = in.peek(); if (token == JsonToken.BEGIN_OBJECT) { // 单个对象场景:解析后加入集合 Object item = elementAdapter.read(in); resultList.add(item); } else if (token == JsonToken.BEGIN_ARRAY) { // 数组场景:逐个解析元素加入集合 in.beginArray(); while (in.hasNext()) { Object item = elementAdapter.read(in); resultList.add(item); } in.endArray(); } return resultList; } }; } }
3. 注册适配器并执行反序列化
创建Gson实例时注册自定义适配器,即可兼容两种JSON格式的解析:
// 初始化带适配器的Gson实例 Gson gson = new GsonBuilder() .registerTypeAdapterFactory(new SingleOrArrayTypeAdapterFactory()) .create(); // 解析单个Client对象的JSON String singleClientJson = "{\"code\":200,\"message\":\"success\",\"data\":{\"id\":1,\"name\":\"ClientA\"}}"; Data<Client> singleData = gson.fromJson(singleClientJson, new TypeToken<Data<Client>>() {}.getType()); // 解析Client数组的JSON String arrayClientJson = "{\"code\":200,\"message\":\"success\",\"data\":[{\"id\":1,\"name\":\"ClientA\"},{\"id\":2,\"name\":\"ClientB\"}]}"; Data<Client> arrayData = gson.fromJson(arrayClientJson, new TypeToken<Data<Client>>() {}.getType()); // 同样适配Provider类 String providerJson = "{\"code\":200,\"message\":\"success\",\"data\":{\"id\":101,\"name\":\"ProviderX\"}}"; Data<Provider> providerData = gson.fromJson(providerJson, new TypeToken<Data<Provider>>() {}.getType());
核心说明
- 适配器会自动识别
data节点的类型(单个对象/数组),统一解析为List<T>,完美适配泛型Data类; - 序列化时可根据列表长度自动切换输出格式,也可修改write方法强制始终输出数组。
内容的提问来源于stack exchange,提问作者Iñigo Dominguez
相关产品推荐
相关产品推荐

