我是靠谱客的博主 野性火车,最近开发中收集的这篇文章主要介绍记录springboot架构下The valid characters are defined in RFC 7230 and RFC 3986问题排查解决The valid characters are defined in RFC 7230 and RFC 3986问题,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

将多个springcloud项目整合成一个单体的springboot工程,前端也换了架构,由于前端新架构没有将所有特殊字符比方[]中括号进行转义,开发整合过程中偶尔出现带中括号参数的请求报错400的问题,请求未到程序代码,后端Tomcat里就报错:

The valid characters are defined in RFC 7230 and RFC 3986问题

报错日志:

09-Apr-2019 14:55:11.427 信息 [http-nio-8089-exec-8] org.apache.coyote.http11.Http11Processor.service Error parsing HTTP request header
 Note: further occurrences of HTTP header parsing errors will be logged at DEBUG level.
 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:479)
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:684)
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:806)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1498)
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.lang.Thread.run(Thread.java:748)

排查发现是tomcat高版本的规范限制导致的:本工程springboot2.3集成的tomcat9版本的,中括号这种字符前端get请求必须转义。

tomcat8.0以上版本遵从RFC规范添加了对Url的特殊字符的限制,url中只允许包含英文字母(a-zA-Z)、数字(0-9)、-_.~四个特殊字符以及保留字符( ! * ’ ( ) ; : @ & = + $ , / ? # [ ] ) (26*2+10+4+18=84)这84个字符,请求中出现了{}大括号或者[],所以tomcat报错。

设置RelaxedQueryChars允许此字符(建议),设置requestTargetAllows选项(Tomcat 8.5中不推荐)。也可以降级为旧版本之一(不推荐-安全性)。

根据https://tomcat.apache.org/tomcat-9.0-doc/config/systemprops.html tomcat配置说明,requestTargetAllowis 设置允许不受欢迎字符。

实践验证一种方法设置松弛的QueryChars属性:

/**
 * 解决异常信息:
 *  java.lang.IllegalArgumentException:
 *      Invalid character found in the request target. The valid characters are defined in RFC 7230 and RFC 3986
 * @return
 */
@Bean
public ConfigurableServletWebServerFactory webServerFactory() {
    TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
    factory.addConnectorCustomizers(new TomcatConnectorCustomizer() {
        @Override
        public void customize(Connector connector) {
            connector.setProperty("relaxedQueryChars", "|{}[]");
        }
    });
    return factory;
}                

问题解决。

但是另一个分支不存在该问题,比对排查可能是笔者清理调整最终版分支架构导致的,最终发现跟pom依赖里的顺序有关,

最开始添加了一个底层log组件,该组件的pom里引入了spring-boot-starter-web,spring-boot-starter-web中引入了spring-boot-starter-tomcat,由此导致以上问题。

本架构本来没有使用tomcat,使用了undertow,undertow性能好一些:

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-undertow</artifactId>
        </dependency>

Spring Boot内嵌容器支持Tomcat、Jetty、Undertow。

关于Undertow等分析对比参考:

Tomcat vs. Jetty vs. Undertow: Comparison of Spring Boot Embedded Servlet Containers:   https://examples.javacodegeeks.com/enterprise-java/spring/tomcat-vs-jetty-vs-undertow-comparison-of-spring-boot-embedded-servlet-containers/

Spring Boot 容器选择 Undertow 而不是 Tomcat:  https://www.cnblogs.com/duanxz/p/9337022.html 

 

备注:

另一种类似异常参考:https://blog.csdn.net/baiHoo_chen/article/details/85221852


    Invalid character found in method name. HTTP method names must be token
原因:
   产生这个问题的原因是页面表单提交了大量的数据,而这些数据量可能超过了Tomcat 定义的Header头内容,那么很好解决了,只要设置一下Tomcat的maxHttpHeaderSize

 解决问题如下:

server:
  address: 0.0.0.0
  port: 8080
  max-http-header-size: 10240000
  tomcat:
    max-http-header-size: 10240000
    max-http-post-size: 10240000       

                                                                                                                                                               

 

 

最后

以上就是野性火车为你收集整理的记录springboot架构下The valid characters are defined in RFC 7230 and RFC 3986问题排查解决The valid characters are defined in RFC 7230 and RFC 3986问题的全部内容,希望文章能够帮你解决记录springboot架构下The valid characters are defined in RFC 7230 and RFC 3986问题排查解决The valid characters are defined in RFC 7230 and RFC 3986问题所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(57)

评论列表共有 0 条评论

立即
投稿
返回
顶部