Android中Retrofit GET请求使用@Body报错的解决求助
问题解决步骤
1. 核心错误原因解析
- GET请求不允许携带请求体,原代码中
@GET方法搭配@Body注解违反HTTP规范,直接触发Non-body HTTP method cannot contain @Body错误。 - 修改后用
@Query但传入LoginRequest对象同样错误:@Query用于传递单个URL查询参数,Retrofit无法自动将自定义对象转换为单个参数值。
2. 修正Retrofit接口定义
根据你的后端GetuserName接口逻辑(接收username字符串参数),调整UserService如下:
public interface UserService { // 对应后端根据username查询用户的接口 @GET("person/") Call<List<People>> loginUser(@Query("username") String username); }
注意:后端返回的是
List<People>集合,原接口用Call<LoginResponse>会导致JSON解析失败,需将返回类型与后端响应结构匹配。
3. 修正MainActivity中的调用逻辑
调用接口时传入LoginRequest中的username参数,并调整回调泛型类型以匹配接口返回值:
public void loginUser(LoginRequest loginRequest) { // 传入LoginRequest中的用户名参数 Call<List<People>> loginResponseCall = ApiClient.getService().loginUser(loginRequest.getUsername()); loginResponseCall.enqueue(new Callback<List<People>>() { @Override public void onResponse(Call<List<People>> call, Response<List<People>> response) { if(response.isSuccessful()) { List<People> peopleList = response.body(); // 验证用户是否存在、密码是否匹配 if(peopleList != null && !peopleList.isEmpty()) { People user = peopleList.get(0); if(user.getPassword().equals(loginRequest.getPassword())) { startActivity(new Intent(MainActivity.this, Visitor.class).putExtra("data", user)); finish(); } else { Toast.makeText(MainActivity.this, "密码错误", Toast.LENGTH_LONG).show(); } } else { Toast.makeText(MainActivity.this, "用户不存在", Toast.LENGTH_LONG).show(); } } else { Toast.makeText(MainActivity.this, "请求失败,请稍后重试", Toast.LENGTH_LONG).show(); } } @Override public void onFailure(Call<List<People>> call, Throwable t) { Toast.makeText(MainActivity.this, t.getLocalizedMessage(), Toast.LENGTH_LONG).show(); } }); }
4. 额外优化建议
- 登录逻辑使用GET请求存在安全风险(密码会暴露在URL中),建议后端改为
POST接口,通过请求体传递用户名和密码。 - 确保Retrofit实例配置了Gson转换器,用于JSON数据解析:
Retrofit retrofit = new Retrofit.Builder() .baseUrl("你的后端基础URL") .addConverterFactory(GsonConverterFactory.create()) .build();
内容的提问来源于stack exchange,提问作者Reborn
相关产品推荐
相关产品推荐

