Retrofit POST请求被转为GET请求的异常排查与修复方案咨询
问题原因与修复方案
这个问题我之前排查过,本质是Retrofit结合OkHttp时的默认行为:当你定义了@POST接口,但没有提供任何请求体相关的注解(比如@Body、@FormUrlEncoded+@Field、@Multipart+@Part),同时接口参数只有@Path路径参数时,OkHttp会自动把这个POST请求转换成GET请求——因为HTTP规范里POST请求通常应该携带请求体,而无请求体的POST在实现上容易被客户端做这种兼容转换。
具体修复方案(按推荐程度排序)
方案1:改成GET请求(最推荐)
从你的接口路径api/v2/reviews/vote/{vote}/dislike/{dislike}来看,这个请求只是传递路径参数,没有需要提交的表单或JSON数据,完全符合GET请求的使用场景。直接把@POST改成@GET即可:@GET("api/v2/reviews/vote/{vote}/dislike/{dislike}") Single<SimpleResponse> postReviewLike(@Path("vote") Integer vote, @Path("dislike") Integer dislike);这种方式既符合HTTP语义,又避免了Retrofit/OkHttp的自动转换问题。
方案2:给POST请求添加空请求体
如果后端要求必须用POST,那可以手动给接口添加一个空的请求体。首先修改接口定义,添加@Body参数:@POST("api/v2/reviews/vote/{vote}/dislike/{dislike}") Single<SimpleResponse> postReviewLike( @Path("vote") Integer vote, @Path("dislike") Integer dislike, @Body RequestBody emptyBody );调用的时候传入一个空的RequestBody:
RequestBody emptyBody = RequestBody.create(MediaType.parse("application/json"), "{}"); // 或者更简洁的方式(OkHttp 4+) RequestBody emptyBody = RequestBody.create(new byte[0], null); yourApiService.postReviewLike(voteVal, dislikeVal, emptyBody);方案3:用@FormUrlEncoded配合空字段
另一种方式是给接口添加@FormUrlEncoded注解,然后加一个不需要的空字段:@FormUrlEncoded @POST("api/v2/reviews/vote/{vote}/dislike/{dislike}") Single<SimpleResponse> postReviewLike( @Path("vote") Integer vote, @Path("dislike") Integer dislike, @Field("dummy") String dummy );调用时传入空字符串即可:
yourApiService.postReviewLike(voteVal, dislikeVal, "");这种方式比较取巧,不如前两种优雅,仅作为备选。
内容的提问来源于stack exchange,提问作者Bogdan Krivenko
相关产品推荐
相关产品推荐

