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

Android Retrofit2认证开发中response.body().string()为空问题排查

问题分析与解决方案

你的问题核心是Retrofit配置与服务器响应格式不匹配,导致response.body()为空,即使服务器确实返回了"SUCCESS"。以下是具体原因和修复步骤:

核心原因

  1. Gson转换器无法处理纯文本响应:你在Retrofit中添加了GsonConverterFactory,但服务器返回的是纯文本"SUCCESS"而非标准JSON格式。Gson会尝试将纯文本解析为JSON对象,解析失败后返回null的body。
  2. 未检查响应状态码:你直接读取response.body(),但如果服务器返回非200-300的状态码(比如用户已存在时返回409),response.body()会为null,此时应该读取response.errorBody()。
  3. ResponseBody.string()的流特性:流只能读取一次,若后续需要复用响应内容,必须先转为字符串保存。

修复方案(二选一)

方案一:添加字符串转换器处理纯文本响应

适合服务器确实返回纯文本的场景:

  1. 添加Scalars转换器依赖:在app模块的build.gradle中添加:
implementation 'com.squareup.retrofit2:converter-scalars:2.9.0'
  1. 修改RetrofitClient配置:将ScalarsConverterFactory放在Gson转换器之前:
private RetrofitClient () {
    retrofit = new Retrofit.Builder()
            .baseUrl(BASE_URL)
            .addConverterFactory(ScalarsConverterFactory.create())
            .addConverterFactory(GsonConverterFactory.create())
            .build();
}
  1. 修改API接口返回类型:将Call<ResponseBody>改为Call<String>:
public interface API {
    @POST("register") // 替换为实际接口路径
    Call<String> createUser(@Body User user);
}
  1. 更新RegisterActivity回调逻辑:添加状态码检查:
call.enqueue(new Callback<String>() {
    @Override
    public void onResponse(Call<String> call, Response<String> response) {
        if (response.isSuccessful()) {
            String s = response.body();
            if ("SUCCESS".equals(s)) {
                Toast.makeText(RegisterActivity.this, "Successfully registered. Please login", Toast.LENGTH_LONG).show();
                startActivity(new Intent(RegisterActivity.this, LoginActivity.class));
            } else {
                Toast.makeText(RegisterActivity.this, "User already exists!", Toast.LENGTH_LONG).show();
            }
        } else {
            try {
                String errorMsg = response.errorBody().string();
                Toast.makeText(RegisterActivity.this, errorMsg, Toast.LENGTH_LONG).show();
            } catch (IOException e) {
                e.printStackTrace();
                Toast.makeText(RegisterActivity.this, "Request failed", Toast.LENGTH_LONG).show();
            }
        }
    }

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

方案二:修改服务器返回JSON格式(推荐)

更符合RESTful规范,便于后续扩展:

  1. 服务器返回标准JSON:比如注册成功返回{"status":"SUCCESS"},用户已存在返回{"status":"EXISTS"}。

  2. 创建响应实体类:

public class ApiResponse {
    private String status;

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }
}
  1. 修改API接口返回类型:
public interface API {
    @POST("register")
    Call<ApiResponse> createUser(@Body User user);
}
  1. 更新回调逻辑:
call.enqueue(new Callback<ApiResponse>() {
    @Override
    public void onResponse(Call<ApiResponse> call, Response<ApiResponse> response) {
        if (response.isSuccessful()) {
            ApiResponse apiResponse = response.body();
            if (apiResponse != null && "SUCCESS".equals(apiResponse.getStatus())) {
                Toast.makeText(RegisterActivity.this, "Successfully registered. Please login", Toast.LENGTH_LONG).show();
                startActivity(new Intent(RegisterActivity.this, LoginActivity.class));
            } else {
                Toast.makeText(RegisterActivity.this, "User already exists!", Toast.LENGTH_LONG).show();
            }
        } else {
            try {
                String errorMsg = response.errorBody().string();
                Toast.makeText(RegisterActivity.this, errorMsg, Toast.LENGTH_LONG).show();
            } catch (IOException e) {
                e.printStackTrace();
                Toast.makeText(RegisterActivity.this, "Request failed", Toast.LENGTH_LONG).show();
            }
        }
    }

    @Override
    public void onFailure(Call<ApiResponse> call, Throwable t) {
        Toast.makeText(RegisterActivity.this, t.getMessage(), Toast.LENGTH_LONG).show();
    }
});

额外调试建议

  • 在回调中打印response.code()和response.message(),确认服务器返回的状态码是否符合预期。
  • 用Postman或curl直接调用服务器接口,验证返回内容和Content-Type是否正确。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 09:28:09