Android Retrofit中同时处理JSON对象与JSON数组的方法
解决API响应data字段类型不一致的解析问题
问题原因
你的API在请求成功时,data字段返回JSON对象;请求失败时,data返回空JSON数组。但你的POJO类中data字段定义为Data类型,Gson解析时遇到数组会抛出com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY异常。
解决方案
方案一:自定义Gson TypeAdapter(推荐)
通过自定义TypeAdapter,让Gson在解析Data类型时自动处理对象和数组两种情况:
- 实现
TypeAdapter<Data>类
public class DataTypeAdapter extends TypeAdapter<Data> { @Override public void write(JsonWriter out, Data value) throws IOException { if (value == null) { out.nullValue(); return; } new Gson().toJson(value, Data.class, out); } @Override public Data read(JsonReader in) throws IOException { JsonToken token = in.peek(); if (token == JsonToken.BEGIN_ARRAY) { // 跳过空数组,返回null in.beginArray(); in.endArray(); return null; } else if (token == JsonToken.BEGIN_OBJECT) { // 正常解析Data对象 return new Gson().fromJson(in, Data.class); } else { in.skipValue(); return null; } } }
- 配置Retrofit时使用自定义Gson实例
Gson customGson = new GsonBuilder() .registerTypeAdapter(Data.class, new DataTypeAdapter()) .create(); Retrofit retrofit = new Retrofit.Builder() .baseUrl("https://dev2.test/") .addConverterFactory(GsonConverterFactory.create(customGson)) .build();
方案二:用JsonElement接收data字段再手动转换
修改SendOtpAPI类的data字段类型为JsonElement,后续手动判断类型并转换:
public class SendOtpAPI { @SerializedName("status") @Expose private String status; @SerializedName("code") @Expose private String code; @SerializedName("description") @Expose private String description; @SerializedName("data") @Nullable @Expose private JsonElement data; // 原有getter、setter方法不变 // 新增方法,将JsonElement转为Data对象 public Data getDataAsDataObject() { if (data == null) return null; try { if (data.isJsonObject()) { return new Gson().fromJson(data, Data.class); } } catch (Exception e) { e.printStackTrace(); } return null; } }
调用接口后,通过getDataAsDataObject()方法获取Data实例,若data是数组则返回null。
方案三:协调后端统一返回格式
如果后端可以修改,建议让失败时data字段返回null或空对象{},而非空数组,这样就能直接使用原有POJO解析,无需客户端额外处理。
内容的提问来源于stack exchange,提问作者Android
相关产品推荐
相关产品推荐

