SpringBoot启动的Tomcat不接收特殊字符而报400Bad Request错误

现象

GET请求中输入*[ \ ] ^ ` { | }*符号,服务器报400错误。

curl 'http://localhost:9999/xxxx/drivers?page=1&size=20&realname=\xxxx' \
-H 'Accept-Encoding: gzip, deflate' \
-H 'Accept-Language: zh,en;q=0.9,ja;q=0.8,zh-TW;q=0.7,fr;q=0.6,zh-CN;q=0.5' \
-H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.75 Safari/537.36' \
-H 'Accept: application/json, text/plain, */*' \
-H 'userId: 453' \
-H 'Connection: keep-alive' \
-H 'token: 1e6966ec2fafdbbd53ef53124cc3e5ae' \
--compressed

错误如下,也就是400:

<html lang="en"><head><title>HTTP Status 400 – Bad Requesttitle><style type="text/css">h1 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;} h2 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:16px;} h3 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:14px;} body {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} b {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;} p {font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;} a {color:black;} a.name {color:black;} .line {height:1px;background-color:#525D76;border:none;}style>head><body><h1>HTTP Status 400 – Bad Requesth1>body>html>

原因

根据RFC7230中2.3.6的规定,字符\充当是不允许出现在HTTP header field values中。还根据Tomcat的doc文档中关于relaxedQueryCharsrelaxedPathChars 的描述,默认情况下,字符“< > [ \ ] ^ ` { | }”是不允许出现在相应地方。因此服务器返回400错误,也就是请求包含了不允许的字符,所以是个Bad Request。

解决办法

  1. 在项目中、对Tomcat服务器进行自定义设置,允许出现某些字符。
  2. 对URL进行转义。改动量可能有点大。

在SpringBoot中设置可接收\的方法如下:

import org.springframework.boot.web.embedded.tomcat.TomcatConnectorCustomizer;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.stereotype.Component;

@Component
public class CustomContainer implements WebServerFactoryCustomizer<TomcatServletWebServerFactory> {

  @Override
  public void customize(TomcatServletWebServerFactory factory) {
    factory.addConnectorCustomizers((TomcatConnectorCustomizer) connector -> {
      connector.setAttribute("relaxedQueryChars", "\\");
      connector.setAttribute("relaxedPathChars", "\\");
//      connector.setPort(8888);
    });
  }
}

结论

上面的代码可行,可以解决所提及的bug,但是此问题严格意义上来说不能算作一个bug,因此先不做修改,只当做一个备用解决方案。

参考:
https://stackoverflow.com/questions/41053653/tomcat-8-is-not-able-to-handle-get-request-with-in-query-parameters/51212677#51212677
https://stackoverflow.com/questions/51703746/setting-relaxedquerychars-for-embedded-tomcat

你可能感兴趣的:(J2EE)