SpringBoot内嵌tomcat处理有特殊字符转义的问题

 更新时间:2023年06月26日 09:18:59   作者:苏暮沉觞  
这篇文章主要介绍了SpringBoot内嵌tomcat处理有特殊字符转义的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

SpringBoot内嵌tomcat处理有特殊字符转义

前段时间在发生了前端调后台接口失败,原因是url中存在特殊字符,SpringBoot自带的tomcat无法正常解析,返回400 bad Request。

网上搜了一下,发现是因为tomcat高版本中,更加严格按照 RFC 3986规范进行访问解析,而 RFC 3986规范规定Url中只允许包含英文字母(a-zA-Z)、数字(0-9)、-_.~4个特殊字符以及所有保留字符(RFC3986中指定了以下字符为保留字符:! * ’ ( ) ; : @ & = + $ , / ? # [ ])。。

在这里记录一下解决过程。

SpringBoot版本为 2.2.5release(不同版本的解决方式可能不同)。

实际解决方式(针对于使用SpringBoot内置的Tomcat)

添加下面的配置Bean。

    /**
     * 配置转义字符,解决当请求路径中特殊字符,高版本tomcat解析失败的问题
     */
    @Bean
    public ServletWebServerFactory webServerFactory() {
        TomcatServletWebServerFactory fa = new TomcatServletWebServerFactory();
        fa.addConnectorCustomizers(connector -> {
            connector.setProperty("relaxedQueryChars", "(),/:;<=>?@[\\]{}");
            connector.setProperty("rejectIllegalHeader", "false");
        });
        return fa;
    }

(该内容只是用于记录,具体是否有效没有测试过)如果你不是使用SpringBoot的tomcat启动项目,那你就需要在tomcat的配置文件中添加以下配置信息,并重新启动。

org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true

Springboot2中修改tomcat参数支持请求特殊符号

解决:java.lang.IllegalArgumentException: Invalid character found in ...

使用Springboot2中内置的tomcat启动项目时候,前端发来的请求报错:

java.lang.IllegalArgumentException: Invalid character found in the request target. 
The valid characters are defined in RFC 7230 and RFC 3986     
at org.apache.coyote.http11.Http11InputBuffer.parseRequestLine(Http11InputBuffer.java:488) ~[tomcat-embed-core-9.0.33.jar:9.0.33]     
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:260) ~[tomcat-embed-core-9.0.33.jar:9.0.33]     
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) [tomcat-embed-core-9.0.33.jar:9.0.33]     
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868) [tomcat-embed-core-9.0.33.jar:9.0.33]     
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1594) [tomcat-embed-core-9.0.33.jar:9.0.33]     
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-9.0.33.jar:9.0.33]     
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_144]     
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_144]     
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-9.0.33.jar:9.0.33]     
at java.lang.Thread.run(Thread.java:748) [na:1.8.0_144]

这段报错的意思是:请求中含有无效字符,有效的字符在RFC 7230和RFC 3986中定义

出现这个错误的原因是:我们在前后台交互的时候请求的参数,其中含有“{}”“[]”这些特殊符号,在高版本的tomcat中含有这些字符的请求会被拦截。

例如:http://localhost:8080/sendMail?content=[1007]...

解决方法

springboot项目中增加一个配置,将webServerFactory方法加入到springboot启动类中,配置文件代码如下:

import org.apache.catalina.connector.Connector;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class TomcatConfig {
    @Bean
    public TomcatServletWebServerFactory webServerFactory() {
        TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
        factory.addConnectorCustomizers((Connector connector) -> {
            connector.setProperty("relaxedPathChars", "\"<>[\\]^`{|}");
            connector.setProperty("relaxedQueryChars", "\"<>[\\]^`{|}");
        });
        return factory;
    }
}

这样就解决问题啦!

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Java实现序列化与反序列化的简单示例

    Java实现序列化与反序列化的简单示例

    序列化与反序列化是指Java对象与字节序列的相互转换,一般在保存或传输字节序列的时候会用到,下面有两个Java实现序列化与反序列化的简单示例,不过还是先来看看序列和反序列化的具体概念:
    2016-05-05
  • Springboot通过谷歌Kaptcha 组件生成图形验证码功能

    Springboot通过谷歌Kaptcha 组件生成图形验证码功能

    Kaptcha是谷歌开源的一款简单实用的图形验证码组件。我个人推荐它的最大原因是容易上手,采用约定大于配置的方式,快速契合到项目中,这篇文章主要介绍了Springboot通过谷歌Kaptcha组件生成图形验证码的方法,需要的朋友可以参考下
    2023-05-05
  • Java大批量导出Excel数据的优化过程

    Java大批量导出Excel数据的优化过程

    几十万上百万行的数据是很常见的。本文主要介绍了Java大批量导出Excel数据的优化过程,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-08-08
  • SpringBoot使用Validator进行参数校验实战教程(自定义校验,分组校验)

    SpringBoot使用Validator进行参数校验实战教程(自定义校验,分组校验)

    这篇文章主要介绍了SpringBoot使用Validator进行参数校验(自定义校验,分组校验)的实战教程,本文通过示例代码给大家介绍的非常详细,需要的朋友参考下吧
    2023-07-07
  • java模式匹配之蛮力匹配

    java模式匹配之蛮力匹配

    这篇文章主要介绍了java模式匹配之蛮力匹配的相关资料和代码,需要的朋友可以参考下
    2015-05-05
  • Java使用正则表达式验证用户名和密码的方法

    Java使用正则表达式验证用户名和密码的方法

    这篇文章主要介绍了Java使用正则表达式验证用户名和密码的方法,本文给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-09-09
  • 如何从Java接口的角度切入静态工厂模式

    如何从Java接口的角度切入静态工厂模式

    静态工厂模式是一种改进的获取实例的方法。通常我们会使用new关键字调用类的构造方法来创建一个对象。静态工厂可以根据用户传入的参数来动态地实例化对象,避免一次性实例化所有对象所带来的性能浪费,同时也降低了耦合性。
    2021-06-06
  • java迭代器移除元素出现并发修改异常的原因及解决

    java迭代器移除元素出现并发修改异常的原因及解决

    这篇文章主要介绍了java迭代器移除元素出现并发修改异常的原因及解决,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • Java实现将彩色PDF转为灰度PDF的示例代码

    Java实现将彩色PDF转为灰度PDF的示例代码

    本文以Java代码为例介绍如何实现将彩色PDF文件转为灰度(黑白)的PDF文件,文中的示例代码讲解详细,感兴趣的小伙伴快跟随小编一起学习一下吧
    2022-03-03
  • SpringCloud Alibaba项目实战之nacos-server服务搭建过程

    SpringCloud Alibaba项目实战之nacos-server服务搭建过程

    Nacos 是阿里巴巴推出来的一个新开源项目,这是一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。本章节重点给大家介绍SpringCloud Alibaba项目实战之nacos-server服务搭建过程,感兴趣的朋友一起看看吧
    2021-06-06

最新评论