Retrofit GET请求报错:Non-body HTTP method cannot contain @Body 求助
解决Retrofit GET请求报错与JSON解析问题
嘿,刚接触Retrofit遇到这种问题很正常,咱们一步步来解决:
首先先搞定你最头疼的那个报错——java.lang.IllegalArgumentException: Non-body HTTP method cannot contain @Body。这个问题本质很简单:Retrofit里的GET请求不允许带@Body注解,因为GET请求是通过URL传递参数,不会携带请求体,你给GET接口加@Body肯定会报错。
第一步:修复GetDataService接口
直接把@Body参数去掉,GET请求不需要传请求体:
// GetDataService.java @GET("Animal.ashx") Call<TableResponse> getAll(); // 删掉@Body和对应的参数
然后在Fragment里调用的时候,也不用传new TableResponse()了:
// Fragment中修改调用代码 Call<TableResponse> call = service.getAll(); // 去掉括号里的参数
第二步:修正JSON实体类的映射问题
看你的JSON响应,里面是animals和birds两个数组,但你的TableResponse类里用了@SerializedName("animal")(少了个s),还有get方法叫getTables(),这完全和JSON字段不匹配,肯定解析不到数据。咱们重新整理实体类:
- 先写Animal类(对应JSON里的animals数组元素):
public class Animal { @SerializedName("animalName") @Expose private String animalName; @SerializedName("animalID") @Expose private Integer animalID; // 生成getter方法就行,setter按需加 public String getAnimalName() { return animalName; } public Integer getAnimalID() { return animalID; } }
- 再写Bird类(对应birds数组元素):
public class Bird { @SerializedName("birdsId") @Expose private Integer birdsId; @SerializedName("birdsname") @Expose private String birdsname; public Integer getBirdsId() { return birdsId; } public String getBirdsname() { return birdsname; } }
- 修正TableResponse类,保证和JSON字段完全对应:
public class TableResponse { @SerializedName("animals") @Expose private List<Animal> animals = null; @SerializedName("birds") @Expose private List<Bird> birds = null; @SerializedName("ID") @Expose private Integer ID; // 构造方法和getter方法 public TableResponse(List<Animal> animals, List<Bird> birds, Integer ID) { this.animals = animals; this.birds = birds; this.ID = ID; } public List<Animal> getAnimals() { return animals; } public List<Bird> getBirds() { return birds; } public Integer getID() { return ID; } }
第三步:修改Fragment的解析逻辑
现在你能正确拿到animals和birds数组了,接下来把数据加载到GridView里。比如你想显示所有动物和鸟类的名称,可以合并两个列表:
call.enqueue(new Callback<TableResponse>() { @Override public void onResponse(Call<TableResponse> call, Response<TableResponse> response) { if (response.isSuccessful() && response.body() != null) { List<String> allNames = new ArrayList<>(); // 把动物名称加进去 List<Animal> animals = response.body().getAnimals(); if (animals != null) { for (Animal animal : animals) { allNames.add(animal.getAnimalName()); } } // 把鸟类名称加进去 List<Bird> birds = response.body().getBirds(); if (birds != null) { for (Bird bird : birds) { allNames.add(bird.getBirdsname()); } } // 转成数组给适配器 String[] nameArray = allNames.toArray(new String[0]); gridView.setAdapter(new TableViewAdapter(getContext(), nameArray)); } } @Override public void onFailure(Call<TableResponse> call, Throwable t) { // 这里加个错误提示,方便调试 Toast.makeText(getContext(), "加载失败:" + t.getMessage(), Toast.LENGTH_SHORT).show(); } });
额外小提醒
- 检查下Base URL是否正确,
http://demoapp.in/结尾的斜杠Retrofit会自动和接口路径拼接,不用额外处理; - 如果这个API需要传参数(比如那个ID),GET请求要用
@Query注解,比如:
调用的时候传入对应的ID就行。@GET("Animal.ashx") Call<TableResponse> getAll(@Query("ID") Integer id);
内容的提问来源于stack exchange,提问作者sherin
相关产品推荐
相关产品推荐

