Retrofit 2中自定义HTTP方法AUTH无法使用,请求体报错求助
解决Retrofit自定义AUTH方法带请求体抛出IllegalArgumentException的问题
你遇到的这个问题是因为OkHttp默认会校验HTTP方法是否允许携带请求体,对于自定义的AUTH方法,它默认判定为不允许带请求体,所以即使你在Retrofit的@HTTP注解里设置了hasBody = true,OkHttp依然会抛出异常。
原因分析
OkHttp内部的okhttp3.Method类维护了一个HTTP方法的映射表,其中默认只有POST、PUT、PATCH等少数方法被标记为允许携带请求体。自定义的AUTH方法不在这个列表里,所以当请求尝试携带body时,就会触发IllegalArgumentException。
解决方案
我们需要让OkHttp认可AUTH方法允许携带请求体,最直接的方式是通过反射修改OkHttp内部的方法映射:
- 在你的应用初始化的地方(比如
Application的onCreate()方法)添加以下代码,提前修改OkHttp的方法规则:
try { // 获取Method类的METHODS静态字段 Field methodsField = okhttp3.Method.class.getDeclaredField("METHODS"); methodsField.setAccessible(true); // 获取当前的方法映射表 Map<String, okhttp3.Method> methods = (Map<String, okhttp3.Method>) methodsField.get(null); // 添加AUTH方法,参数分别是方法名、是否允许请求体、是否允许响应体 methods.put("AUTH", new okhttp3.Method("AUTH", true, true)); } catch (NoSuchFieldException | IllegalAccessException e) { e.printStackTrace(); }
- 确保你的Retrofit实例使用的是这个修改后的OkHttpClient:
OkHttpClient client = new OkHttpClient.Builder() // 可以添加你的其他配置,比如日志拦截器 .addInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY)) .build(); Retrofit retrofit = new Retrofit.Builder() .baseUrl("你的基础URL") .client(client) .addConverterFactory(GsonConverterFactory.create()) .build();
额外注意事项
- 这种反射方式依赖于OkHttp的内部实现,虽然在你使用的3.8.1版本中有效,但如果后续OkHttp版本修改了内部结构,可能需要调整。
- 还要确认你的服务器端支持
AUTH方法携带请求体,否则即使客户端不报错,服务器也可能返回错误。
另外,检查你的Retrofit接口定义,你当前的写法是正确的:
@Headers("Content-Type: application/json") @HTTP(method = "AUTH", path = "login/{deviceId}", hasBody = true) Call<Success> getLogin(@Path("deviceId") int deviceId, @Body RequestBody password);
内容的提问来源于stack exchange,提问作者Chetak Bhimani
相关产品推荐
相关产品推荐

