springboot报错:java.lang.IllegalArgumentException: Invalid character found in the request target.

问题描述

前端vue项目将一个数组转化为一个JSON字符串传到后端。
vue部分代码

dataFormSubmit () {
        console.log('commit to java')
        console.log(this.dataReturn)
        this.$http({
          url: this.$http.adornUrl('/rl/bs/init'),
          method: 'get',
          params: this.$http.adornParams({
            'test': JSON.stringify(this.dataReturn),
            'orderId': this.orderId
          })
        }).then(({data}) => {
          if (data && data.code === 0) {
            this.$message({
              message: '操作成功',
              type: 'success',
              duration: 1500,
              onClose: () => {
                this.visible = false
                this.dataReturn = []
              }
            })
          } else {
            this.$message.error(data.msg)
          }
        })
      }

前端报错信息如下:

Access to XMLHttpRequest at 'http://192.168.43.167:8080/renren-fast/rl/bs/init?t=1588645562664&page=1&limit=10&test=[%7B%22nodeId%22:%2253cd42ebf0af4b4ab166983dae6d1fa6%22,%22userName%22:%22admin%22,%22password%22:%22test%22%7D,%7B%22nodeId%22:%22603050967a334c9298e4a3fe24acb372%22,%22userName%22:%22test%22,%22password%22:%22123%22%7D]' from origin 'http://localhost:8001' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

后台报错信息如下:


 Note: further occurrences of HTTP request 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:468)
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:260)
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:860)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1598)
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.lang.Thread.run(Thread.java:748)

问题分析

首先,由前端报错信息可知,这是一个典型的跨域问题,百度上可以搜到一大把的解决方案,但是在我实践的过程中,如果将要传输的JSON字符串改为普通的字符串,比如”hello world",将不会出现这个问题,于是可以排除是简单的跨域问题。再看后端springboot的报错信息,可知为无效字符引发的问题,且这个错误只在首次接受到含有无效字符的JSON字符串的时候会报错,所以很容易被忽略。
可以确定,这个问题是高版本tomcat中的新特性:就是严格按照 RFC 3986规范进行访问解析,而 RFC 3986规范定义了Url中只允许包含英文字母(a-zA-Z)、数字(0-9)、-_.~4个特殊字符以及所有保留字符(RFC3986中指定了以下字符为保留字符:! * ’ ( ) ; : @ & = + $ , / ? # [ ])。而我们的系统在通过地址传参时,在url中传了一段json,传入的参数中有”{“不在RFC3986中的保留字段中,所以会报这个错。
一般情况下解决这个问题需要修改tomcat的catalina.properties文件,增加一点配置,但是我的电脑上并没有安装tomcat,使用的也是在springboot中配置的tomcat,并没有catalina.properties,也不知道application.properties文件中能否加入那些配置。在我的记忆中,好像可以在springboot的启动类中加点代码可以解决。
一番百度之下,找到了解决方案:

public TomcatServletWebServerFactory webServerFactory() {
		TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
		factory.addConnectorCustomizers((Connector connector) -> {
			connector.setProperty("relaxedPathChars", "\"<>[\\]^`{|}");
			connector.setProperty("relaxedQueryChars", "\"<>[\\]^`{|}");
		});
		return factory;
	}

参考博文地址:
https://blog.csdn.net/qq_32365919/article/details/82055800
https://www.jianshu.com/p/b6911b45bc02

猜你喜欢

转载自blog.csdn.net/weixin_43562234/article/details/105943674