我们遇到了一个问题,嵌入式Tomcat从LegacyCookieProcessor
抛出IllegalArgumentException
。它抛出一个500 HTTP响应代码。
我们需要处理异常并对其进行处理(具体地说,将其作为400发送)。
典型的@ExceptionHandler(IllegalArgumentException.class)
似乎没有被触发,Google似乎只给出处理Spring Boot特定异常的结果。
下面是一个重现这种行为的例子。您可以通过下载包含SpringWeb的初始项目来执行该示例(https://start.spring.io/)在版本2.1.5中。释放然后将以下两个类添加到项目中。
DemoControllerAdvice。JAVA
package com.example.demo;
import java.util.HashMap;
import java.util.Map;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
@RestControllerAdvice
public class DemoControllerAdvice {
@ExceptionHandler(IllegalArgumentException.class)
@ResponseStatus(HttpStatus.FORBIDDEN)
public Map<String, String> forbiddenHandler() {
Map<String, String> map = new HashMap<>();
map.put("error", "An error occurred.");
map.put("status", HttpStatus.FORBIDDEN.value() + " " + HttpStatus.FORBIDDEN.name());
return map;
}
}
DemoRestController。JAVA
package com.example.demo;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class DemoRestController {
@GetMapping(value = "/working")
public void working() {
throw new java.lang.IllegalArgumentException();
}
@GetMapping(value = "/not-working")
public String notWorking(@RequestParam String demo) {
return "You need to pass e.g. the character ^ as a request param to test this.";
}
}
然后,启动服务器并在浏览器中请求以下URL:
http://localhost:8080/working
在控制器中手动抛出一个非法argumentException
。然后它被ControllerAdvice捕获,因此将生成一个JSON字符串,其中包含在DemoControllerAdvice
http://localhost:8080/not-工作?demo=test^123
Tomcat抛出了一个IllegalArgumentException
,因为无法解析请求参数(因为无效字符^
)。然而,ControllerAdvice没有捕捉到异常。它显示Tomcat提供的默认HTML页面。它还提供了与DemoControllerAdvice
中定义的不同的错误代码
在日志中显示以下消息:
o、 阿帕奇。郊狼。http11。Http11Processor:解析HTTP请求头时出错注意:HTTP请求解析错误的进一步出现将在调试级别记录。
JAVAlang.IllegalArgumentException:在请求目标中找到无效字符。有效字符在org的RFC 7230和RFC 3986中定义。阿帕奇。郊狼。http11。Http11InputBuffer。parseRequestLine(Http11InputBuffer.java:467)~[tomcat-embed-core-9.0.19.jar:9.0.19]
这是Tomcat本身的一个特性,如本文所述。
但是,您可以这样做,允许您期望的特殊字符作为请求的一部分,并自己处理它们。
首先,您需要通过如下设置relaxedQueryChars来允许需要处理的特殊字符。
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.stereotype.Component;
@Component
public class TomcatCustomizer implements
WebServerFactoryCustomizer<TomcatServletWebServerFactory> {
@Override
public void customize(TomcatServletWebServerFactory factory) {
factory.addConnectorCustomizers((connector) -> {
connector.setAttribute("relaxedQueryChars", "^");
});
}
}
然后处理每个请求中的特殊字符,或者创建一个拦截器并在公共位置处理它。
要在请求中单独处理它,您可以这样做。
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class DemoRestController {
@GetMapping(value = "/working")
public void working() {
throw new java.lang.IllegalArgumentException();
}
@GetMapping(value = "/not-working")
public String notWorking(@RequestParam String demo) {
if (demo.contains("^")) {
throw new java.lang.IllegalArgumentException("^");
}
return "You need to pass e.g. the character ^ as a request param to test this.";
}
}
您可能还想参考这个答案来决定您是否真的需要这个修复程序。
我有时会在pom中看到以下声明。xml。。。 如您所见,sping-boo-starter-web被声明为tomcat-embed-jasper。 是不是sping-boo-starter-web已经有一个嵌入式tomcat了?为什么一些开发人员仍然声明tomcat-embed-jasper以及boot-starter-web?还是有什么原因?
我需要将我的Spring Boot ZuL网关中的MaxKeepAliverRequests值修改为高于默认值100的值。注意到该值未在Spring Boo的公共属性列表中公开,我尝试通过@Configuration class设置属性: 但似乎并没有起到预期的效果。有没有一种合适的方法可以让我更改没有通过Spring common properties公开的Tomcat属性?
在将非spring应用程序转换为Spring Boot时,您希望使用现有上下文。嵌入tomcat中的xml文件。 使用Spring Boot 1.5.1和Tomcat 8.5.11 TomcatEmbeddedServletContainerFactory配置 检查数据库连接的方法, 那么如何在Spring Boot中加载现有的context.xml。
问题内容: 我需要在Tomcat中启动Hazelcast,而无需单独的war文件。因此,将hazelcast.jar放入lib文件夹中的hazelczast.xml某处…接下来呢?还是不可能? 问题答案: 第一步是好的,只需将Hazelcast lib和配置放在Tomcat的libs文件夹中。接下来,如果您不需要单独的WAR文件,则是构建一个小的Valve类来启动/关闭Hazelcast节点。问题
使用Spring Boot和启用LoadTimeWeaving的嵌入式tomcat,缓存方面在运行时没有任何影响,但我们看到在日志中编织的情况很好。 下面是配置,LoadTimeWeave与模式一起启用,作为用于缓存的AsheJ Spring代理-javaagent:..//Spring-仪表-4.3.3。释放。罐子 原木 围绕这个有很多讨论。编织发生在RestartClassLoader上,不确
我正在使用NetBeans IDE和带有Spring Boot的Maven。每当我运行我的应用程序不止一次,我就会得到这个错误: O.A.Coyote.http11.http11nioprotocol:无法启动与ProtocolHandler关联的终结点[“http-nio-8080”] spring boot java.lang.IllegalStateException:Tomcat连接器处于