You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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类型时自动处理对象和数组两种情况:

  1. 实现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;
        }
    }
}
  1. 配置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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 22:20:28