项目场景:
Springboot项目使用postman调用拼接url且需要传入Json格式参数的接口,在params里填入Json格式的入参,调用后未进入接口且报出Error parsing HTTP request header,Invalid character found in the request target.The valid characters are defined in RFC 7230 and RFC3986
问题描述
接口大致如下,确定请求方式和路径没有错误,Springboot项目也不存在mvc配置之类的。
@PostMapping(value = "/test")
public xxx test(String json) {
//参数json需要传入json格式的
}
原因分析:
tomcat版本原因
导致上述问题是因为tomcat自8.5.x系列的:8.5.12 之后版本、8.0.x系列的:8.0.42 之后版本、7.0.x系列的:7.0.76 之后版本对URL参数做了比较规范的限制,必须遵循RFC 7230 and RFC 3986规范,对于非保留字字符(json格式的请求参数)必须做转义操作,否则会抛出Invalid character found in the request target. The valid characters are defined in RFC 7230 and RFC 3986错误信息。就是严格按照 RFC 3986规范进行访问解析,而 RFC 3986规范定义了Url中只允许包含英文字母(a-zA-Z)、数字(0-9)、-_.~4个特殊字符以及所有保留字符(RFC3986中指定了以下字符为保留字符:! * ’ ( ) ; : @ & = + $ , / ? # [ ])。而我们的系统在通过地址传参时,在url中传了一段json,传入的参数中有"{"不在RFC3986中的保留字段中,所以会报这个错。
解决方案:
Springboot内置tomcat,不建议从版本入手解决,推荐对参数做转义操作
-
遵循7230 and RFC 3986规范,对于非保留字字符做转义操作。将[替换为%5B,]替换为%5D。
url编码网站:https://meyerweb.com/eric/tools/dencoder/
-
遵循7230 and RFC 3986规范,使用保留字字符,不使用非保留字符
-
降低tomcat版本
-
将json数据进行urlencode编码
-
修改配置文件。配置tomcat/conf下的catalina.properties
URL特殊字符需转义
1、空格换成加号(+)
2、正斜杠(/)分隔目录和子目录
3、问号(?)分隔URL和查询
4、百分号(%)制定特殊字符
5、#号指定书签
6、&号分隔参数
转义字符的原因:
如果你的表单使用get方法提交,并且提交的参数中有“&”等特殊符的话,如果不做处理,在service端就会将&
后面的作为另外一个参数来看待。例如
表单的action为list.jsf?act=go&state=5
则提交时通过request.getParameter可以分别取得act和state的值。
如果你的本意是act='go&state=5'这个字符串,那么为了在服务端拿到act的准确值,你必须对&进行转义
url转义字符原理:
将这些特殊的字符转换成ASCII码,格式为:%加字符的ASCII码,即一个百分号%,后面跟对应字符的
ASCII(16进制)码值。例如 空格的编码值是"%20"。
URL特殊符号及对应的十六进制值编码:
1. + URL 中+号表示空格 %2B
2. 空格 URL中的空格可以用+号或者编码 %20
3. / 分隔目录和子目录 %2F
4. ? 分隔实际的 URL 和参数 %3F
5. % 指定特殊字符 %25
6. # 表示书签 %23
7. & URL 中指定的参数间的分隔符 %26
8. = URL 中指定参数的值 %3D