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

Retrofit请求报错:Expected a string but was BEGIN_OBJECT 求助

解决Retrofit报错:Expected a string but was BEGIN_OBJECT

兄弟,这个报错我太熟了——核心原因一目了然:你告诉Retrofit要接收一个String类型的响应,但服务器实际返回的是标准JSON对象,和你定义的StudentListResponse实体类结构完全匹配,可接口里却用了Call<String>,这直接导致Gson解析器懵了:本来要解析成对象,结果你硬让它转成字符串,不报错才怪!

下面一步步给你把问题捋顺:

1. 修正Retrofit接口的返回类型

把原来返回Call<String>的接口,改成返回你定义的实体类Call<StudentListResponse>:

@GET("studentlist/{schoolid}/{driverid}")
Call<StudentListResponse> getStudentList(@Path("schoolid") String schoolid,@Path("driverid") String driverid);

2. 完善你的实体类(补全内部类)

看你给出的实体类代码,内部的StudentsList类没写全,得把它补完整,每个字段都用@SerializedName和服务器返回的JSON字段一一对应,比如:

public class StudentListResponse {
    @SerializedName("status")
    private String status;
    @SerializedName("res")
    private List<StudentsList> resp = new ArrayList<>();

    // Getter & Setter
    public String getStatus() { return status; }
    public void setStatus(String status) { this.status = status; }
    public List<StudentsList> getResp() { return resp; }
    public void setResp(List<StudentsList> resp) { this.resp = resp; }

    // 对应服务器返回的单个学生数据的内部类
    public static class StudentsList {
        // 这里的字段要完全匹配服务器返回的学生字段,比如student_id、name之类的
        @SerializedName("student_id")
        private String studentId;
        @SerializedName("student_name")
        private String studentName;

        // 每个字段的Getter & Setter
        public String getStudentId() { return studentId; }
        public void setStudentId(String studentId) { this.studentId = studentId; }
        public String getStudentName() { return studentName; }
        public void setStudentName(String studentName) { this.studentName = studentName; }
    }
}

3. 修改Activity中的请求回调逻辑

现在响应是实体类了,你得把原来处理字符串的代码改成处理StudentListResponse,直接拿实体类里的学生列表给RecyclerView:

Bundle bundle = getIntent().getExtras();
schoolname = bundle.getString("school_id");
driverid = bundle.getString("dri_number");

// 注意这里的Call类型改成StudentListResponse
Call<StudentListResponse> call = api.getStudentList(schoolname, driverid);
call.enqueue(new Callback<StudentListResponse>() {
    @Override
    public void onResponse(Call<StudentListResponse> call, Response<StudentListResponse> response) {
        Toast.makeText(StudentListActivity.this, response.message(), Toast.LENGTH_SHORT).show();
        if (response.isSuccessful()){
            StudentListResponse studentResponse = response.body();
            if (studentResponse != null){
                // 可以先打印状态看看是否成功
                Toast.makeText(StudentListActivity.this, studentResponse.getStatus(), Toast.LENGTH_SHORT).show();
                // 把学生列表传给RecyclerView的初始化方法
                writeRecycler(studentResponse.getResp());
            } else {
                Log.i("onEmptyResponse", "Returned empty response");
            }
        }
    }
    @Override
    public void onFailure(Call<StudentListResponse> call, Throwable t) {
        Toast.makeText(StudentListActivity.this, t.getMessage(), Toast.LENGTH_SHORT).show();
    }
});

最后检查一个关键配置

确保你的Retrofit实例已经添加了Gson转换器,不然实体类没法被正确解析,创建Retrofit的代码应该是这样的:

Retrofit retrofit = new Retrofit.Builder()
        .baseUrl("你的服务器基础URL,比如http://xxx.xxx.com/api/")
        .addConverterFactory(GsonConverterFactory.create()) // 这个必须加!
        .build();

这样改完之后,Retrofit就会自动把服务器返回的JSON对象解析成你定义的StudentListResponse实体类,再也不会出现类型不匹配的报错了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 09:16:23