项目使用okhttp请求第三方接口不成功,对方服务器出现RFC 7230 and RFC 3986错误
,原因如下
Tomcat在 7.0.73, 8.0.39, 8.5.7 版本后,添加了对于http头的验证。具体来说,就是添加了些规则去限制HTTP头的规范性
org.apache.tomcat.util.http.parser.HttpParser#IS_NOT_REQUEST_TARGET[]中定义了一堆not request target
if(IS_CONTROL[i] || i > 127 || i == 32 || i == 34 || i == 35 || i == 60 || i == 62 || i == 92 || i == 94 || i == 96 || i == 123 || i == 124 || i == 125) {
IS_NOT_REQUEST_TARGET[i] = true;
}
转换过来就是以下字符(对应10进制ASCII看):
- 键盘上那些控制键:(<32或者=127)
- 非英文字符(>127)
- 空格(32)
- 双引号(34)
- #(35)
- <(60)
- >(62)
- 反斜杠(92)
- ^(94)
- TAB上面那个键,我也不晓得嫩个读(96)
- {(123)
- }(124)
- |(125)
项目代码
@POST("apis/notice/sendNotice")
Call<SpNoticeResult> sendSpNotice(@Query("content") String content,
@Query("title") String title);
结合上边分析,原因就是发送post请求时,参数被拼接到url中,包含特殊字符导致.所以,把请求参数放在请求体里发送就好了!
修改如下:
-
把
@Query
改成@Field
-
添加
@FormUrlEncoded
注解,否则会报错@Field parameters can only be used with form encoding
@POST("apis/notice/sendNotice")
@FormUrlEncoded
Call<SpNoticeResult> sendSpNotice(@Field("content") String content,
@Field("title") String title);
本人对okhttp并不是太熟悉,但是老项目在用,为了解决这个bug也是费了好大事,差点重写代码(哈哈...草率了)
看到下面这张图才豁然开朗,找到最优的解决方案
参考: