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

Retrofit+GSON解析报错:Expected BEGIN_OBJECT解决指引

解决Retrofit+GSON解析时的JsonSyntaxException问题

兄弟,你的问题核心是数据类型不匹配加上逻辑判断错误,我帮你一步步拆解解决:

先搞懂报错原因

报错com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING的意思是:GSON本来要解析一个JSON对象(也就是{...}这种键值对格式),但实际收到的是纯字符串(比如直接返回"exist"而非{"response":"exist"}),或者你的代码对返回值的类型声明完全错误。

分步解决

第一步:先确认接口返回的真实数据

先通过抓包工具(比如Charles、Fiddler)或者给Retrofit加日志拦截器,明确接口到底返回的是什么:

  • 如果是{"response":"exist"}这种JSON对象,按「实体类映射」方案处理
  • 如果是纯字符串(比如"exist"或不带引号的exist),按「直接接收字符串」方案处理

第二步:针对JSON对象返回的情况(假设接口确实返回{"response":"exist"})

1. 正确定义Register实体类

你的实体类必须和JSON结构完全对应,要有一个response字段:

public class Register {
    private String response;

    // 必须提供getter方法,否则GSON无法读取字段值
    public String getResponse() {
        return response;
    }

    public void setResponse(String response) {
        this.response = response;
    }
}

2. 修正onResponse里的逻辑

你之前直接把response.body()(这是Register对象)和字符串比较,完全错误!要先取出对象里的response字段再判断,还要先确保请求成功:

call.enqueue(new Callback<Register>() {
    @Override
    public void onResponse(Call<Register> call, Response<Register> response) {
        // 先判断请求是否成功,且返回体不为null
        if (response.isSuccessful() && response.body() != null) {
            String result = response.body().getResponse();
            // 注意:你代码里写的`exiest`是拼写错误,要和接口返回的`exist`保持一致
            switch (result) {
                case "ok":
                    Toast.makeText(MainActivity.this, "Registration is Successfully", Toast.LENGTH_SHORT).show();
                    break;
                case "exist":
                    Toast.makeText(MainActivity.this, "Already Exists", Toast.LENGTH_SHORT).show();
                    break;
                case "error":
                    Toast.makeText(MainActivity.this, "Registration Error", Toast.LENGTH_SHORT).show();
                    break;
                default:
                    Toast.makeText(MainActivity.this, "Unknown response", Toast.LENGTH_SHORT).show();
            }
        } else {
            // 处理HTTP状态码异常的情况(比如404、500)
            Toast.makeText(MainActivity.this, "Request failed: " + response.code(), Toast.LENGTH_SHORT).show();
        }
    }

    @Override
    public void onFailure(Call<Register> call, Throwable t) {
        Toast.makeText(MainActivity.this, t.getMessage(), Toast.LENGTH_SHORT).show();
        // 打印详细日志方便排查问题
        t.printStackTrace();
    }
});

第三步:如果接口返回的是纯字符串

那你需要把Retrofit接口的返回类型改成Call<String>,直接处理字符串:

// 假设你的Retrofit接口方法是这样的:
// @POST("your/register/url")
// Call<String> registerUser(@Body UserData data);

Call<String> call = yourRetrofitService.registerUser(yourData);
call.enqueue(new Callback<String>() {
    @Override
    public void onResponse(Call<String> call, Response<String> response) {
        if (response.isSuccessful() && response.body() != null) {
            String result = response.body();
            // 如果接口返回的是带引号的字符串(比如"exist"),可以去掉引号再比较
            String cleanResult = result.trim().replace("\"", "");
            switch (cleanResult) {
                case "ok":
                    Toast.makeText(MainActivity.this, "Registration is Successfully", Toast.LENGTH_SHORT).show();
                    break;
                case "exist":
                    Toast.makeText(MainActivity.this, "Already Exists", Toast.LENGTH_SHORT).show();
                    break;
                case "error":
                    Toast.makeText(MainActivity.this, "Registration Error", Toast.LENGTH_SHORT).show();
                    break;
                default:
                    Toast.makeText(MainActivity.this, "Unknown response", Toast.LENGTH_SHORT).show();
            }
        }
    }

    @Override
    public void onFailure(Call<String> call, Throwable t) {
        Toast.makeText(MainActivity.this, t.getMessage(), Toast.LENGTH_SHORT).show();
    }
});

额外注意点

  • 检查拼写:你代码里的exiest和接口返回的exist不一致,会导致判断失效,一定要修正
  • 永远先判断response.isSuccessful()和response.body() != null,避免空指针异常
  • 加日志拦截器可以快速定位问题,比如给Retrofit配置:
OkHttpClient client = new OkHttpClient.Builder()
    .addInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY))
    .build();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 04:18:31