GSON处理JSON时遇空数组匹配对象问题求助
解决GSON解析空数组替代空对象的问题
这个坑我之前踩过!GSON默认的解析逻辑确实没法自动处理这种“用空数组[]代替空对象null”的奇葩JSON格式,不过咱们可以通过自定义TypeAdapter来完美适配,思路很简单:反序列化时判断当前字段如果是空数组,就返回null(或者你需要的空对象),否则正常解析成目标对象。
1. 写一个通用的自定义TypeAdapter
这个Adapter可以复用在所有需要处理的对象/集合类型上:
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; public class EmptyArrayAsNullAdapter<T> extends TypeAdapter<T> { private final TypeAdapter<T> delegate; public EmptyArrayAsNullAdapter(TypeAdapter<T> delegate) { this.delegate = delegate; } @Override public void write(JsonWriter out, T value) throws IOException { delegate.write(out, value); } @Override public T read(JsonReader in) throws IOException { // 检测到当前是数组类型 if (in.peek() == JsonToken.BEGIN_ARRAY) { in.beginArray(); // 判断数组是否为空 if (!in.hasNext()) { in.endArray(); return null; // 空数组直接返回null,也可以改成return new T()返回空对象(需确保T有无参构造) } else { // 非空数组但期望是对象的情况,根据业务需求处理,这里直接抛异常 throw new IOException("Expected object but found non-empty array"); } } else { // 正常解析对象 return delegate.read(in); } } }
2. 把Adapter注册到Gson实例
创建Gson的时候,将自定义Adapter绑定到目标类型上。比如假设你的实体类是Prize,业务模型类是AwardModel:
import com.google.gson.Gson; import com.google.gson.GsonBuilder; public class GsonParser { public static void main(String[] args) { // 注册单个对象类型的Adapter Gson gson = new GsonBuilder() .registerTypeAdapter(Prize.class, new EmptyArrayAsNullAdapter<>(new Gson().getAdapter(Prize.class))) .create(); // 测试空数组场景 String emptyJson = "{\"prizes\":[]}"; AwardModel emptyModel = gson.fromJson(emptyJson, AwardModel.class); // 此时emptyModel.getPrizes()会是null // 测试非空正常场景 String nonEmptyJson = "{\"prizes\":[{\"year\":\"1902\",\"category\":\"physics\",\"share\":\"2\",\"motivation\":\"\\\"in recognition of the extraordinary service they rendered by their researches into the infl...\"}]}"; AwardModel nonEmptyModel = gson.fromJson(nonEmptyJson, AwardModel.class); // 正常解析出Prize对象 } }
3. 针对List集合的特殊处理
如果你的prizes是List<Prize>类型,需要用TypeToken来指定泛型类型:
import com.google.gson.reflect.TypeToken; // 注册List<Prize>类型的Adapter Type prizeListType = new TypeToken<List<Prize>>() {}.getType(); Gson gson = new GsonBuilder() .registerTypeAdapter(prizeListType, new EmptyArrayAsNullAdapter<>(new Gson().getAdapter(prizeListType))) .create();
4. 仅针对特定字段处理(非全局)
如果只有个别字段有这个问题,不想全局生效,可以用@JsonAdapter注解直接标记在字段上:
public class AwardModel { // 单个对象字段 @JsonAdapter(EmptyArrayAsNullAdapter.class) private Prize prizes; // 或者List集合字段 // @JsonAdapter(EmptyArrayAsNullAdapter.class) // private List<Prize> prizes; }
小提示
- 如果业务需要空数组返回空对象而非
null,可以把Adapter里的return null改成return new T(),但要确保目标类有无参构造函数。 - 如果JSON里偶尔出现非空数组但期望是对象的异常场景,可以根据业务需求调整异常处理逻辑(比如跳过该字段、返回默认值等)。
内容的提问来源于stack exchange,提问作者Crushinz
相关产品推荐
相关产品推荐

