【SpringMVC问题】Invalid character found in the request target. The valid characters are defined in RFC

3 篇文章 0 订阅

问题

访问链接http://localhost:8080/spring03/requestParam7?addresses[0].city=beijing时,页面显示Invalid character found in the request target. The valid characters are defined in RFC 7230 and RFC 3986

在这里插入图片描述
意思为:在请求目标中找到无效字符,有效字符在RFC 7230和RFC 3986中定义。

经了解,这个问题是高版本tomcat中的新特性:就是严格按照 RFC 3986规范进行访问解析,而 RFC 3986规范定义了Url中只允许包含英文字母(a-z A-Z)、数字(0-9)、- _ . ~4个特殊字符以及所有保留字符(RFC3986中指定了以下字符为保留字符:! * ' ( ) ; : @ & = + $ , / ? # [ ])。

RFC3986文档对Url的编解码问题做出了详细的建议,指出了哪些字符需要被编码才不会引起Url语义的转变,以及对为什么这些字符需要编码做出了相应的解释。

  1. 在US-ASCII字符集中没有的可打印字符:Url中只允许使用可打印字符。US-ASCII码中的10-7F字节全都表示控制字符,这些字符都不能直接出现在Url中。同时,对于80-FF字节(ISO-8859-1),由于已经超出了US-ACII定义的字节范围,因此也不可以放在Url中。
  2. 保留字符:Url可以划分成若干个组件,协议、主机、路径等。有一些字符(: / ? # [ ] @)是用作分隔不同组件的。例如:冒号用于分隔协议和主机,/用于分隔主机和路径,?用于分隔路径和查询参数,等等。还有一些字符(! $ & ' ( ) * + , ; =)用于在每个组件中起到分隔作用的,如=用于表示查询参数中的键值对,&符号用于分隔查询多个键值对。当组件中的普通数据包含这些特殊字符时,需要对其进行编码

如果需要在URL中用到特殊字符,需要将这些特殊字符换成相应的十六进制的值

  • 不安全字符:有一些字符,当他们直接放在Url中的时候,可能会引起解析程序的歧义。这些字符被视为不安全字符,原因有很多。
  • 空格:Url在传输的过程,或者用户在排版的过程,或者文本处理程序在处理Url的过程,都有可能引入无关紧要的空格,或者将那些有意义的空格给去掉。
  • 引号以及<>:引号和尖括号通常用于在普通文本中起到分隔Url的作用
  • #:通常用于表示书签或者锚点
  • %:百分号本身用作对不安全字符进行编码时使用的特殊字符,因此本身需要编码
  • { } | \ ^ [ ] ~ `:某一些网关或者传输代理会篡改这些字符

需要注意的是,对于Url中的合法字符,编码和不编码是等价的,但是对于上面提到的这些字符,如果不经过编码,那么它们有可能会造成Url语义的不同。因此对于Url而言,只有普通英文字符和数字,特殊字符$-_.+!*'()还有保留字符,才能出现在未经编码的Url之中。其他字符均需要经过编码之后才能出现在Url中。

但是由于历史原因,目前尚存在一些不标准的编码实现。例如对于~符号,虽然RFC3986文档规定,对于波浪符号~,不需要进行Url编码,但是还是有很多老的网关或者传输代理会。

我的url为http://localhost:8080/spring03/requestParam7?addresses[0].city=beijing&addresses[1].province=hebei

由此我知道我需要将url中的[]符号进行url编码([%5b ]%5d)才可以使用,由此我将上述url改为以下地址后,成功显示
http://localhost:8080/spring03/requestParam7?addresses%5b0%5d.city=beijing&addresses%5b1%5d.province=hebei

解决办法

综上,有3种解决方案:

  1. 使用Tomcat7.0.69之前的版本;
  2. 对url的特殊字符进行转义
  3. 修改tomcat配置文件

方法一:使用Tomcat7.0.69之前的版本;

方法二:对url的特殊字符进行转义

URL中只能使用US-ASCII字符集可以显示的字符,如果需要在URL中使用不属于此字符集的字符,就要使用特殊的符号对该字符进行编码,如最常使用的空格用%20来表示。

除了那些无法显示的字符外,还需要在URL中对那些保留(reserved)字符和不安全(unsafe)字符进行编码。

保留字符是指那些在URL中具有特定意义的字符,不安全字符是指那些在URL中没有特殊含义,但在URL所在的上下文中可能具有特殊意义的字符。

所有可以在浏览器上对特殊字符进行url编码,对应编码对应如下

部分保留字符和不安全字符及其URL编码

字符描述用法编码
;分号保留%3B
/斜线保留%2F
?问号保留%3F
:冒号保留%3A
@“at”符号保留%4O
=等号保留%3D
&“和”符号保留%26
<小于号不安全%3C
>大于号不安全%3E
双引号不安全%22
#井号不安全%23
%百分号不安全%25
{左大括号不安全%7B
}右大括号不安全%7D
|竖线不安全%7C
\反斜线不安全%5C
^加字号不安全%5E
~波浪不安全%7E
[左中括号不安全%5B
]右中括号不安全%5D
`反单引号不安全%60
空格不安全%20

另一种方式,就是发请求前,进行

URLEncoder.encode(requestURI,"UTF-8");

此方法适用于 执行发出请求的是ajax或其他客户端程序(可以发出http请求的编程语言,都有encode()相关支持)。

然后在后台接收请求后decode()

String params = request.getParameter(PARAMS);
params = URLDecoder.decode(params,"UTF-8");

方法三:修改tomcat配置文件

修改tomcat配置文件server.xml,在Connector配置项添加relaxedQueryChars="[]|{}^&#x5c;&#x60;&quot;&lt;&gt;"这句话就好了,即下面代码块的最后一行是需要添加的。

<Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443"
			   relaxedQueryChars="[]|{}^&#x5c;&#x60;&quot;&lt;&gt;"/>

关于&#x5c等编码对应查看如下
https://dev.w3.org/html5/html-author/charref

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陈小哥cw

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值