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

Android Retrofit调用API报错:Expected BEGIN_OBJECT but was STRING at $.data

问题:Retrofit解析响应时出现IllegalStateException错误

1. API调用定义

@POST(ApiConstant.ADD_MEMBER)
Call<MemberResponse> addMember(@Body Map<String, Object> map);

2. 请求调用代码

HashMap<String, Object> list = new HashMap<>();
list.put("code", TinyDB.getInstance().getString(PrefrenceConstent.TRAINER_CODE));
list.put("first_name", TinyDB.getInstance().getString(PrefrenceConstent.KEY_NAME));
list.put("email", TinyDB.getInstance().getString(PrefrenceConstent.KEY_USER_EMAIL));
list.put("contact", TinyDB.getInstance().getString(PrefrenceConstent.KEY_USER_MOBILE));
list.put("last_name", "Null");

try {
    Response<MemberResponse> responseAllInvites = ApiBuilder.getApiInterfaceCoachPro().addMember(list).execute();
    if (responseAllInvites.body() != null) {
        Timber.e("Response: %s", responseAllInvites.body().getData());
        MemberInfo invitationsList = responseAllInvites.body().getData();
        String member_code = invitationsList.getMember_code();
        Timber.e("Member Code: %s", member_code);
    }
} catch (Exception e) {
    return Result.failure();
}

3. POJO类定义

public class MemberResponse {
@SerializedName("data")
@Expose
private MemberInfo data;

@SerializedName("Message")
@Expose
private String message;

public MemberInfo getData() {
    return data;
}

public void setData(MemberInfo data) {
    this.data = data;
}

public String getMessage() {
    return message;
}

public void setMessage(String message) {
    this.message = message;
}}

4. 预期响应JSON

{
"data": {
    "id": 84,
    "member_code": "testcrm-72807-47474-12"
},
"Message": "Member details were successfully created!"}

5. 错误信息

java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 10 path $.data


问题原因

错误提示明确说明:解析器期望$.data是一个对象(BEGIN_OBJECT对应JSON中的{}),但实际返回的是字符串类型。这意味着接口返回的真实JSON中,data字段并非你预期的对象结构,而是一段字符串(比如"data": "操作失败"这类格式),导致Gson无法将其解析为MemberInfo对象,抛出异常。

排查步骤

  1. 打印完整响应内容:在请求逻辑中添加代码,打印接口返回的完整响应(包括错误响应),确认data字段的真实类型:
    try {
        Response<MemberResponse> responseAllInvites = ApiBuilder.getApiInterfaceCoachPro().addMember(list).execute();
        // 打印完整响应内容(注意errorBody().string()只能调用一次)
        if (!responseAllInvites.isSuccessful() && responseAllInvites.errorBody() != null) {
            Timber.e("Error Response: %s", responseAllInvites.errorBody().string());
        } else if (responseAllInvites.body() != null) {
            Timber.e("Full Response: %s", new Gson().toJson(responseAllInvites.body()));
        }
        // 原有业务逻辑...
    } catch (Exception e) {
        Timber.e(e);
        return Result.failure();
    }
    
  2. 确认接口返回规则:和后端开发人员确认,接口在不同场景下(比如参数错误、重复提交)的返回格式是否统一,是否存在data字段类型切换的情况。

解决办法

方案1:协调后端统一响应格式

要求后端确保data字段始终为对象类型:

  • 成功时返回预期的对象结构
  • 失败时返回null或空对象{},而非字符串

方案2:修改POJO适配动态类型

如果后端无法修改返回格式,调整MemberResponse的data字段类型,兼容对象和字符串两种情况:

import com.google.gson.JsonElement;

public class MemberResponse {
    @SerializedName("data")
    @Expose
    private JsonElement data;

    @SerializedName("Message")
    @Expose
    private String message;

    public JsonElement getData() {
        return data;
    }

    public void setData(JsonElement data) {
        this.data = data;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

然后在解析时判断类型并处理:

if (responseAllInvites.body() != null) {
    JsonElement dataElement = responseAllInvites.body().getData();
    if (dataElement.isJsonObject()) {
        // 解析为MemberInfo对象
        MemberInfo invitationsList = new Gson().fromJson(dataElement, MemberInfo.class);
        String member_code = invitationsList.getMember_code();
        Timber.e("Member Code: %s", member_code);
    } else if (dataElement.isJsonPrimitive()) {
        // 处理字符串类型的data
        String dataStr = dataElement.getAsString();
        Timber.e("Data content: %s", dataStr);
    }
}

内容的提问来源于stack exchange,提问作者Rohit Barge

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 06:45:30