🧑‍💻 SpringBoot项目中设置Tomcat允许特殊字符参数

🧑‍💻 SpringBoot项目中设置Tomcat允许特殊字符参数

最近在半夜升级一套基于SpringBoot开发的Feedbcak系统时,遇到了意料之外的状况。本来预想可能会有一些业务参数兼容性问题,结果这个问题没出现,却出现大量的的Tomcat报错,请求没有进入业务代码,直接在Tomcat层面400了。

症状

具体的异常如下:

java.lang.IllegalArgumentException: Invalid character found in the 
request target [/feedback?xxx=asdasd&yyy=abc|dedg|hijk]. 
The valid characters are defined in RFC 7230 and RFC 3986

为了避免不必要的麻烦,上面的异常堆栈删改了一些无关的内容。java.lang.IllegalArgumentException,这一看就是参数中出现不该出现的字符了,赶紧把参数复制下来,在本地IDE环境和测试Docker环境验证,结果都没有复现这个问题,请求可以正常进入业务代码。检查了Tomcat版本,本地、测试环境和线上全都是9.0.39,这就奇了怪了!

2024-10-11 00:02:03,165[][main]INFO(DirectJDKLog.javalog173)-Initializing ProtocolHandler ["http-nio-0.0.0.0-8080"]
2024-10-11 00:02:03,166[][main]INFO(DirectJDKLog.javalog173)-Starting service [Tomcat]
2024-10-11 00:02:03,166[][main]INFO(DirectJDKLog.javalog173)-Starting Servlet engine: [Apache Tomcat/9.0.39]

结合The valid characters are defined in RFC 7230 and RFC 3986这段提示,一搜就知道了原因,原来是tomcat8.0以上版本遵从RFC规范添加了对Url的特殊字符的限制,url中只允许包含英文字母(a-zA-Z)、数字(0-9)、-_.~四个特殊字符以及保留字符( ! * ’ ( ) ; : @ & = + $ , / ? # [ ] ) 等各种特殊字符均不被允许,否则就会报上面的错误。

仔细一看,请求的参数中果然有受限制的字符|,即:yyy=abc|dedg|hijk

解决方法

知道了原因,那就好办了,直接问大模型AI如何解决吧(相比于搜索引擎哼哧哼哧漫无边际的找,AI确实在编程辅助方面有很大作用)。

🧑‍💻 SpringBoot项目中设置Tomcat允许特殊字符参数

马上就有了答案,在不降低Tomcat版本的前提下,Tomcat提供了解除限值的方法,分别支持对请求参数和路径设置例外字符的能力。在SpringBoot项目中,有两种方法进行设置。

1️⃣ 配置文件设置

直接在application.propertiesapplication.yml设置。

在application.properties中

server.tomcat.relaxed-path-chars=[,],|,
server.tomcat.relaxed-query-chars=[,],{,},

在application.yml中,你可以这样设置:

server:
  tomcat:
    relaxed-path-chars: "[,],|,"
    relaxed-query-chars: "[,],{,},"

2️⃣ 编码方式设置

在项目中创建一个TomcatServletWebServerFactory的Bean,并添加自定义的Connector配置。

@Configuration
public class TomcatConfig {
    @Bean
    public ConfigurableServletWebServerFactory webServerFactory() {
        TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
        factory.addConnectorCustomizers(connector -> {
            connector.setProperty("relaxedPathChars", "|{}[]");
            connector.setProperty("relaxedQueryChars", "|{}[]");
        });
        return factory;
    }
}

两种方法任选一种即可,笔者照葫芦画瓢,直接在配置文件中增加一条配置:

server.tomcat.relaxed-path-chars=|

重启应用后,400错误果然消失了,问题成功解决。此时看看时间,已然是凌晨2点多😂

尾巴

问题虽然解决了,但还是有一个问题笔者没有找到原因,那就是同一个Docker镜像,跑在测试机群上可以正常处理特殊字符,跑在线上就GG了。照理说都已经用Docker镜像了,同样版本的Tomcat为何会有不一样的表现?这真是个大大的字。

如果有大牛知道原因,还望不吝赐教!

原创不易,如果觉得此文对你有帮助,不妨点赞+收藏+关注,你的鼓励是我持续创作的动力!

高等精灵实验室

原创文章,作者:诺多,如若转载,请注明出处:https://www.huluohu.com/posts/1235/

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
📚️ Githuber MD: 让你的WordPress博客焕发Markdown魅力
上一篇 2024年10月11日 07:30
🌟 Follow:新一代RSS订阅工具,让阅读更有趣!
下一篇 2024年10月13日 07:00

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注