Spring 공식 문서 읽기 - Exceptions
원문 : https://docs.spring.io/spring-framework/reference/web/webmvc/mvc-servlet/exceptionhandlers.html
Spring Framework > Web on Servlet Stack > Spring Web MVC > DispatcherServlet > Exceptions
Exceptions
요청 매핑 중에 예외가 발생하거나 요청 핸들러(예: @Controller)에서 예외가 발생하면, DispatcherServlet은 예외를 해결하고 alternative 처리를 제공하기 위해 -오류 응답이 전형적- HandlerExceptionResolver 빈의 묶음(chain)에 위임한다.
HandlerExceptionResolver implementations :
SimpleMappingExceptionResolver | A mapping between exception class names and error view names. Useful for rendering error pages in a browser application. |
DefaultHandlerExceptionResolver | Resolves exceptions raised by Spring MVC and maps them to HTTP status codes. See also alternative ResponseEntityExceptionHandler and Error Responses. |
ResponseStatusExceptionResolver | Resolves exceptions with the @ResponseStatus annotation and maps them to HTTP status codes based on the value in the annotation. |
ExceptionHandlerExceptionResolver | Resolves exceptions by invoking an @ExceptionHandler method in a @Controller or a @ControllerAdvice class. See @ExceptionHandler methods. |
Chain of Resolvers
당신은 exception resolver chain을 구성할 수 있다. Spring configuration에서 여러 개의 HandlerExceptionResolver 빈을 선언하면 구성할 수 있다. 필요하면 order 속성을 설정할 수 있다. order property가 높을수록 exception resolver는 나중에 위치된다.
HandlerExceptionResolver가 반환할 수 있는 것 (The contract of HandlerExceptionResolver specifies):
- ModelAndView, error view를 가리키는
- 빈(empty) ModelAndView, 예외가 resolver 안에서 처리된 경우라면
- null, 만약 예외가 해결되지 않은 채로 남았다면. 후속 리졸버가 시도할 수 있도록 null을 반환. 그리고 만약 예외가 마지막까지 남는다면, 서블렛 컨테이너에 예외가 분명히 떠오르도록 한다.
*bubble up : to rise to the surface or become obvious (null if the exception remains unresolved, for subsequent resolvers to try, and, if the exception remains at the end, it is allowed to bubble up to the Servlet container.)
MVC Config는 내장 리졸버를 자동으로 선언한다. 빌트인 resolver는 디폴트 Spring MVC 예외, @ResponseStatus 주석이 달린 예외, @ExceptionHandler 메서드를 지원한다. 해당 목록을 사용자 정의하거나 대체할 수 있다.
Container Error Page
예외가 HandlerExceptionResolver에 의해 해결되지 않고, 전파되도록 남겨지거나, 응답 상태가 error status(예: 4xx, 5xx)로 설정된 경우, 서블릿 컨테이너는 HTML로 디폴트 error 페이지를 렌더링할 수 있다. 컨테이너의 디폴트 error 페이지를 사용자 정의하려면, web.xml에서 오류 페이지 매핑을 선언하면 된다. 다음 예제는 그 방법이다:
<error-page>
<location>/error</location>
</error-page>
위 예제에서 예외가 발생하거나 응답에 error status(예: 4xx, 5xx)가 있는 경우, 서블릿 컨테이너는 컨테이너 내에서 configured URL(예: /error)로 ERROR dispatch를 생성합니다. 그 다음 error dispatch를 DispatcherServlet이 처리한다. 어떻게 처리하냐면 @Controller에 매핑할 수 있고, 컨트롤러는 모델과 함께 error view name을 반환하거나 JSON 응답을 렌더링하도록 구현되어 있을 것이다.
다음 예제에서 보여주듯이 :
@RestController
public class ErrorController {
@RequestMapping(path = "/error")
public Map<String, Object> handle(HttpServletRequest request) {
Map<String, Object> map = new HashMap<>();
map.put("status", request.getAttribute("jakarta.servlet.error.status_code"));
map.put("reason", request.getAttribute("jakarta.servlet.error.message"));
return map;
}
}
* Error dispatch?
Dispatches made by the container during exceptions/errors are called error dispatches.
These are usually dispatches to error pages. There is no way to directly do an error dispatch.
A request that has come through an error dispatch will have dispatcher type set to DispatcherType.ERROR.
https://stackoverflow.com/questions/16324114/what-is-an-error-dispatch-in-servlet-processing
http://docs.oracle.com/javaee/6/api/javax/servlet/DispatcherType.html
http://docs.oracle.com/javaee/6/api/javax/servlet/RequestDispatcher.html
Tip
서블릿 API는 Java에서 오류 페이지 매핑을 만드는 방법을 제공하지 않는다. 하지만 WebApplicationInitializer와 미니멀 web.xml 둘다 사용 가능.