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

使用Retrofit实现API登录注册时遇IllegalStateException错误求助

解决java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY错误

核心原因

这个错误的本质是Retrofit定义的响应类型与后端PHP接口返回的JSON格式不匹配:你在代码里期望接收一个JSON对象,但后端实际返回了JSON数组,或者反过来。

排查与解决步骤

1. 先确认后端返回的真实JSON格式

用Postman、curl或者给Retrofit加日志拦截器,打印完整的响应体,明确返回的是对象还是数组:

  • 对象格式示例:{"status":"success","data":{"id":1,"email":"test@example.com"}}
  • 数组格式示例:[{"status":"success","data":{"id":1,"email":"test@example.com"}}]

2. 检查Retrofit接口定义是否匹配

  • 如果后端返回单个对象,接口应定义为返回对象类型:

    public interface AuthService {
        @POST("login.php")
        Call<LoginResponse> login(@Body LoginRequest request);
    
        @POST("register.php")
        Call<RegisterResponse> register(@Body RegisterRequest request);
    }
    

    对应的实体类要和对象结构一致:

    public class LoginResponse {
        private String status;
        private UserData data;
        // 生成getter、setter方法
    }
    
  • 如果后端返回数组,接口要修改为接收数组类型:

    Call<List<LoginResponse>> login(@Body LoginRequest request);
    

    实体类对应数组中的单个对象结构即可。

3. 检查后端PHP的JSON返回逻辑

很多时候问题出在后端:

  • 若返回单个登录/注册结果,应该用echo json_encode($single_response);(输出对象)
  • 若误写成echo json_encode([$single_response]);,会把单个结果包在数组里返回,导致格式不匹配

4. 用日志拦截器辅助排查

给Retrofit添加日志拦截器,直接在Logcat里查看完整的请求和响应:

OkHttpClient client = new OkHttpClient.Builder()
    .addInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY))
    .build();

Retrofit retrofit = new Retrofit.Builder()
    .baseUrl(BASE_URL)
    .client(client)
    .addConverterFactory(GsonConverterFactory.create())
    .build();

通过日志能直观看到后端返回的JSON结构,快速定位格式不匹配的问题。

快速修复方向

  • 若后端返回错误格式:修改PHP代码,确保登录/注册接口返回的JSON结构和前端定义的实体类类型一致
  • 若前端定义错误:调整Retrofit接口的返回类型(对象/数组),匹配后端实际返回格式

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 19:41:04