使用Gson解析空返回对象时触发错误的技术咨询
解决Gson解析空对象/Null字段时的转换错误问题
我之前也碰到过一模一样的问题——当API返回的data字段不是空数组[],而是null或者空对象{}时,Gson在尝试把它转成ArrayList<DataOverviewDto>就会报错。下面给你几个实用的解决方案:
方案1:自定义ArrayList的Json反序列化器
写一个自定义的反序列化器,优雅处理null和非数组的情况,直接返回空ArrayList,避免抛出异常。
public class ArrayListDeserializer<T> implements JsonDeserializer<ArrayList<T>> { private final Class<T> itemClass; public ArrayListDeserializer(Class<T> itemClass) { this.itemClass = itemClass; } @Override public ArrayList<T> deserialize(JsonElement json, Type type, JsonDeserializationContext context) throws JsonParseException { if (json.isJsonNull() || json.isJsonObject()) { // 当data是null或者空对象时,返回空列表 return new ArrayList<>(); } else if (json.isJsonArray()) { // 正常解析数组 JsonArray array = json.getAsJsonArray(); ArrayList<T> list = new ArrayList<>(array.size()); for (JsonElement element : array) { list.add(context.deserialize(element, itemClass)); } return list; } throw new JsonParseException("预期是数组、null或空对象,但实际得到:" + json.getClass().getSimpleName()); } }
创建Gson实例时注册这个反序列化器:
Gson gson = new GsonBuilder() .registerTypeAdapter( new TypeToken<ArrayList<ReportsOverviewDto.DataOverviewDto>>(){}.getType(), new ArrayListDeserializer<>(ReportsOverviewDto.DataOverviewDto.class) ) .create();
这样不管API返回的data是null、{}还是[],都能正确解析成空的ArrayList,不会触发错误。
方案2:解析后手动检查Null值
如果不想改Gson的配置,最简单的办法就是解析后检查data是否为null,要是null就手动初始化空列表:
@Override public void onApiResponse(JSONObject response) { ReportsOverviewDto dto = gson.fromJson(response.toString(), ReportsOverviewDto.class); ArrayList<ReportsOverviewDto.DataOverviewDto> data = dto.getData(); // 如果data是null,就换成空列表 if (data == null) { data = new ArrayList<>(); } // 继续后续处理... }
这个方法简单粗暴,适合快速修复问题,不过不够优雅,适合小项目或者临时解决。
方案3:解析前预处理JSON数据
要是你没法修改Gson的配置,还可以在解析前先修正JSON对象,确保data字段始终是数组类型:
@Override public void onApiResponse(JSONObject response) { // 先修正格式错误的data字段 if (response.isNull("data") || !response.get("data").isJSONArray()) { response.put("data", new JSONArray()); } ReportsOverviewDto dto = gson.fromJson(response.toString(), ReportsOverviewDto.class); ArrayList<ReportsOverviewDto.DataOverviewDto> data = dto.getData(); }
这个方案适合你完全没法控制API返回格式的情况,先把数据标准化再交给Gson解析。
内容的提问来源于stack exchange,提问作者Geoff
相关产品推荐
相关产品推荐

