spring boot 解决Tomcat 报 The valid characters are defined in RFC 7230 and RFC 3986 的问题

tomcat 8.0以后对请求URL做了严格的过滤

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

这可能会遇到一个问题,比如参数中传了一段json,而"{"不在RFC3986中的保留字段中,就会认为是非法的。这时候你的请求压根到不了你的方法就被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.InternalAprInputBuffer.parseRequestLine(InternalAprInputBuffer.java:235)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1028)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:637)
at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.doRun(AprEndpoint.java:2549)
at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:2538)
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:745)

那怎么解决这个问题,你发现在网上找了很多,基本都是:

在tomcat目录conf/catalina.properties最后面添加

tomcat.util.http.parser.HttpParser.requestTargetAllow=|{}
或者:
org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true

暂且不说有没有用,但这个是通过外部tomcat部署项目的方式才能这样修改tomcat的配置文件。而现在很多开发者都使用spring boot的方式进行开发。你会发现,压根就没法直接修改tomcat的配置文件。这时你可能会选择使用jetty或者降低tomcat版本。

难道没有解决方案?别急,这里提供一个解决办法,很简单就能解决这个问题。

在你的spring boot 工程中,添加一个配置文件即可解决:

/*
 * 文件名:RfcConfig.java 版权:Copyright by gogym 描述: 修改人:gogym 修改时间:2018年12月18日 跟踪单号: 修改单号: 修改内容:
 */


import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;


@Configuration
public class RfcConfig
{
    @Bean
    public Integer setRfc()
    {
        // 指定jre系统属性,允许特殊符号, 如{} 做入参,其他符号按需添加。见 tomcat的HttpParser源码。
        System.setProperty("tomcat.util.http.parser.HttpParser.requestTargetAllow", "|{}");
        return 0;
    }

}

如果你想偷懒,直接在启动方法里面添加也可以。

@SpringBootApplication
// 启用服务注册与发现
@EnableDiscoveryClient
// 启用feign进行远程调用
@EnableFeignClients
@ComponentScan(basePackages = {"com.poly"})
public class App
{
    public static void main(String[] args)
    {
        SpringApplication.run(App.class, args);

        System.setProperty("tomcat.util.http.parser.HttpParser.requestTargetAllow","|{}");
    }
}

这样就解决了。希望对你有帮助。当然啦,如果你不想只有处理。那么请求前先对参数进行encode处理也是可以的。

这个错误通常是由于请求URL中存在非法字符导致的,可以在代码中加入一个异常处理器捕获并处理这个错误。 可以在Spring Boot应用程序中创建一个@ControllerAdvice类来处理异常。在这个类中,可以使用@ExceptionHandler注解来处理特定类型的异常。针对这个错误,可以创建一个处理方法,返回一个自定义的错误信息给用户。 例如: ```java @ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler({IllegalArgumentException.class}) public ResponseEntity<String> handleInvalidRequestException(IllegalArgumentException ex) { return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Invalid request: " + ex.getMessage()); } @ExceptionHandler({HttpMessageNotReadableException.class}) public ResponseEntity<String> handleHttpMessageNotReadableException(HttpMessageNotReadableException ex) { return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Invalid request: " + ex.getMessage()); } // 处理请求URL中非法字符的异常 @ExceptionHandler({InvalidRequestUrlException.class}) public ResponseEntity<String> handleInvalidRequestUrlException(InvalidRequestUrlException ex) { return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Invalid request URL: " + ex.getMessage()); } } ``` 在以上代码中,`InvalidRequestUrlException`是一个自定义的异常类,用于表示请求URL中存在非法字符。在处理这个异常的方法中,可以返回一个带有自定义错误信息的`ResponseEntity`对象,其中状态码为400(Bad Request)。 当出现这个异常时,Spring Boot会自动调用对应的异常处理方法,并返回自定义的错误信息给用户。需要注意的是,在抛出异常时,应该将异常信息传递给异常类的构造函数,以便在处理异常时能够获取到异常信息。
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值