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
相关产品推荐
相关产品推荐

