问题描述
SpringBoot访问时,如果长度过长,会出现如下情况:
java.lang.IllegalArgumentException: Invalid character found in the request target [/abcd?%E6%A0%B9%E6%8D%AERFC7230%E4%B8%AD2.3.6%E7%9A%84%E8%A7%84%E5%AE%9A%EF%BC%8C%E5%AD%97%E7%AC%A6\%E5%85%85%E5%BD%93%E6%98%AF%E4%B8%8D%E5%85%81%E8%AE%B8%E5%87%BA%E7%8E%B0%E5%9C%A8HTTP%20header%20field%20values%E4%B8%AD%E3%80%82%E8%BF%98%E6%A0%B9%E6%8D%AETomcat%E7%9A%84doc%E6%96%87%E6%A1%A3%E4%B8%AD%E5%85%B3%E4%BA%8ErelaxedQueryChars%E4%B8%8ErelaxedPathChars%20%E7%9A%84%E6%8F%8F%E8%BF%B0%EF%BC%8C%E9%BB%98%E8%AE%A4%E6%83%85%E5%86%B5%E4%B8%8B%EF%BC%8C%E5%AD%97%E7%AC%A6%E2%80%9C%3C%20%3E%20[%20\%20]%20^%20`%20{%20|%20}%E2%80%9D%E6%98%AF%E4%B8%8D%E5%85%81%E8%AE%B8%E5%87%BA%E7%8E%B0%E5%9C%A8%E7%9B%B8%E5%BA%94%E5%9C%B0%E6%96%B9%E3%80%82%E5%9B%A0%E6%AD%A4%E6%9C%8D%E5%8A%A1%E5%99%A8%E8%BF%94%E5%9B%9E400%E9%94%99%E8%AF%AF%EF%BC%8C%E4%B9%9F%E5%B0%B1%E6%98%AF%E8%AF%B7%E6%B1%82%E5%8C%85%E5%90%AB%E4%BA%86%E4%B8%8D%E5%85%81%E8%AE%B8%E7%9A%84%E5%AD%97%E7%AC%A6%EF%BC%8C%E6%89%80%E4%BB%A5%E6%98%AF%E4%B8%AABad%20Request%E3%80%82%20%E8%A7%A3%E5%86%B3%E5%8A%9E%E6%B3%95%20%E5%9C%A8%E9%A1%B9%E7%9B%AE%E4%B8%AD%E3%80%81%E5%AF%B9Tomcat%E6%9C%8D%E5%8A%A1%E5%99%A8%E8%BF%9B%E8%A1%8C%E8%87%AA%E5%AE%9A%E4%B9%89%E8%AE%BE%E7%BD%AE%EF%BC%8C%E5%85%81%E8%AE%B8%E5%87%BA%E7%8E%B0%E6%9F%90%E4%BA%9B%E5%AD%97%E7%AC%A6%E3%80%82%20%E5%AF%B9URL%E8%BF%9B%E8%A1%8C%E8%BD%AC%E4%B9%89%E3%80%82%E6%94%B9%E5%8A%A8%E9%87%8F%E5%8F%AF%E8%83%BD%E6%9C%89%E7%82%B9%E5%A4%A7%E3%80%82%20%E5%9C%A8SpringBoot%E4%B8%AD%E8%AE%BE%E7%BD%AE%E5%8F%AF%E6%8E%A5%E6%94%B6\%E7%9A%84%E6%96%B9%E6%B3%95%E5%A6%82%E4%B8%8B%EF%BC%9A%20%E2%80%94%E2%80%94%E2%80%94%E2%80%94%E2%80%94%E2%80%94%E2%80%94%E2%80%94%E2%80%94%E2%80%94%E2%80%94%E2%80%94%E2%80%94%E2%80%94%E2%80%94%E2%80%94%20%E7%89%88%E6%9D%83%E5%A3%B0%E6%98%8E%EF%BC%9A%E6%9C%AC%E6%96%87%E4%B8%BACSDN%E5%8D%9A%E4%B8%BB%E3%80%8ClCaSjDiN%E3%80%8D%E7%9A%84%E5%8E%9F%E5%88%9B%E6%96%87%E7%AB%A0%EF%BC%8C%E9%81%B5%E5%BE%AACC%204.0%20BY-SA%E7%89%88%E6%9D%83%E5%8D%8F%E8%AE%AE%EF%BC%8C%E8%BD%AC%E8%BD%BD%E8%AF%B7%E9%99%84%E4%B8%8A%E5%8E%9F%E6%96%87%E5%87%BA%E5%A4%84%E9%93%BE%E6%8E%A5%E5%8F%8A%E6%9C%AC%E5%A3%B0%E6%98%8E%E3%80%82%20%E5%8E%9F%E6%96%87%E9%93%BE%E6%8E%A5%EF%BC%9Ahttps://blog.csdn.net/asahinokawa/article/details/88802348 ]. The valid characters are defined in RFC 7230 and RFC 3986
at org.apache.coyote.http11.Http11InputBuffer.parseRequestLine(Http11InputBuffer.java:494)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:269)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:895)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1722)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
解决方案
@Slf4j
@Configuration
public class TomcatConfig {
/**
* 主要是解决 tomcat,异常字符访问出现的异常,比如链接过长时,会显示404而不是json数据
*/
@Bean
WebServerFactoryCustomizer<TomcatServletWebServerFactory> webServerFactoryCustomizer() {
return factory -> factory.addContextCustomizers(tomcatContextCustomizer());
}
private TomcatContextCustomizer tomcatContextCustomizer() {
return context -> context.getParent().getPipeline().addValve(new TomcatRestErrorReportValve());
}
private static class TomcatRestErrorReportValve extends ErrorReportValve {
@Override
protected void report(Request request, Response response, Throwable e) {
response.setCharacterEncoding(StandardCharsets.UTF_8.name());
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
log.error("后台请求数据异常, status = " + response.getStatus(), e);
try (Writer writer = requireNonNull(response.getReporter(), "后台服务异常")) {
writer.write(RestResult.badRequest("资源访问错误").toJSONString());
writer.flush();
response.finishResponse();
} catch (IOException ex) {
log.error("数据请求异常", ex);
}
}
}
}