Spring Boot에서 포함된 Tomcat 예외 처리
내장된 Tomcat이 던지는 문제가 있습니다.IllegalArgumentException
에서LegacyCookieProcessor
500 HTTP 응답 코드를 보냅니다.
우리는 예외를 처리하고 그것으로 무엇인가를 해야 합니다(구체적으로, 대신 400으로 보냅니다).
전형적인@ExceptionHandler(IllegalArgumentException.class)
트리거되지 않는 것으로 보이며 Google은 스프링 부트 특정 예외를 처리하는 결과만 제공하는 것으로 보입니다.
예:
다음은 동작을 재현하는 예입니다.spring-web(버전 2.1.5의 https://start.spring.io/) )을 포함한 초기 프로젝트를 다운로드하여 예제를 실행할 수 있습니다.풀어주다.그런 다음 다음 두 클래스를 프로젝트에 추가합니다.
데모 컨트롤러 조언.자바
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
안IllegalArgumentException
는 컨트롤러에서 수동으로 던집니다.그런 다음 컨트롤러 어드바이스에 의해 포착되며, 따라서 다음에 정의된 정보를 포함하는 JSON 문자열을 생성합니다.DemoControllerAdvice
http://localhost:8080/not-working?demo=test^123
안IllegalArgumentException
요청 매개 변수를 구문 분석할 수 없기 때문에(잘못된 문자로 인해) Tomcat에 의해 느려집니다.^
). 그러나 컨트롤러 조언에 의해 예외가 발견되지 않습니다.Tomcat에서 제공하는 기본 HTML 페이지를 보여줍니다.또한 에서 정의된 것과 다른 오류 코드를 제공합니다.DemoControllerAdvice
.
로그에 다음 메시지가 표시됩니다.
o.알파벳.알파벳http11.Http11Processor : HTTP 요청 헤더 구문 분석 오류 참고: HTTP 요청 구문 분석 오류의 추가 발생은 DEBUG 수준에서 기록됩니다.
자바.java.java잘못된 인수예외:요청 대상에 잘못된 문자가 있습니다.유효한 문자는 org.apache.coyote의 RFC 7230 및 RFC 3986에 정의되어 있습니다.http11.Http11InputBuffer.parseRequestLine(Http11InputBuffer.java:467) ~[tomcat-embed-core-9.0.19.jar:9.0.19]
이 답변에서 언급한 Tomcat 자체의 특징입니다.
그러나 요청의 일부로 예상되는 특수 문자를 허용하고 직접 처리하여 이러한 작업을 수행할 수 있습니다.
먼저 완화된 문자를 설정하여 처리해야 할 특수 문자를 허용해야 합니다.이렇게 Chars를 쿼리합니다.
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.";
}
}
이 해결책이 정말로 필요한지 여부를 결정하기 위해 이 답변을 참조할 수도 있습니다.
그것을 잡으려고 노력하세요.IllegalArgumentException
필터에서, 그리고 나서 전화하세요.HttpServletResponse.sendError(int sc, String msg);
이것은 아마도 잡힐 것입니다.IllegalArgumentException
하지만 그것은 Tomcat에서 온 것이 아닙니다.하지만 저는 당신이 이미 그것들을 적절하게 처리했다고 생각합니다.
언급URL : https://stackoverflow.com/questions/39376602/handle-embedded-tomcat-exception-in-spring-boot
'it-source' 카테고리의 다른 글
SQL Server에서 SqlDataReader로 데이터를 가져오는 방식은 무엇입니까? (0) | 2023.07.15 |
---|---|
Postgre를 사용하여 DataJpaTest 실행SQL (0) | 2023.07.15 |
JPA Query를 사용하여 데이터를 DB에 삽입하는 방법은 무엇입니까? (0) | 2023.07.15 |
매개 변수 이름 생략, C++ 대 C (0) | 2023.07.10 |
@RestController 메서드는 기본적으로 트랜잭션인 것 같습니다. 왜죠? (0) | 2023.07.10 |