DefaultHandlerExceptionResolver는 스프링 내부에서 발생하는 스프링 예외를 해결한다.
대표적으로 Parameter Binding 시점에 타입이 맞지 않으면 내부에서 TypeMismatchException을 발생하는데, 이 경우 예외가 발생했기 때문에 그냥 두면 Servlet 컨테이너까지 오류가 올라가고, 결과적으로 500 오류가 발생한다.
그런데 Paramter Binding은 대부분 클라이언트가 HTTP 요청 정보를 잘못 호출해서 발생하는 문제다.
HTTP에서는 이런 경우 HTTP 상태 코드 400을 사용하도록 되어 있다.
DefaultHandlerExceptionResolver는 이것을 500 오류가 아니라 HTTP 상태 코드 400오류로 변경해준다.
스프링 내부 오류를 어떻게 처리할지 수 많은 내용이 정의되어 있다.
DefaultHandlerExceptionResolver.handleTypeMismatch를 보면 다음과 같은 코드를 확인할 수 있따.
response.sendError(HttpServletResponse.SC_BAD_REQUEST) (400)
결국 response.sendError()를 통해서 문제를 해결한다.
sendError(400)을 호출했기 때문에 WAS에서 다시 오류페이지(/error)를 내부 요청한다.
@GetMapping("/api/default-handler-ex")
public String defaultException(@RequestParam Integer data) {
return "OK";
}
Integer data에 문자를 입력하면 내부에서 TypeMismatchException이 발생한다.
원래 예외가 터지면 Servlet 컨테이너까지 오류가 올라가서 500에러가 발생해야 하지만 DefaultHandlerExceptionHandler가 500에러를 400에러로 바꿔준다.
public class DefaultHandlerExceptionResolver extends AbstractHandlerExceptionResolver {
@Override
@Nullable
protected ModelAndView doResolveException(
HttpServletRequest request, HttpServletResponse response, @Nullable Object handler, Exception ex) {
try {
if (ex instanceof HttpRequestMethodNotSupportedException) {
return handleHttpRequestMethodNotSupported(
(HttpRequestMethodNotSupportedException) ex, request, response, handler);
}
.....
.....
else if (ex instanceof TypeMismatchException) {
return handleTypeMismatch(
(TypeMismatchException) ex, request, response, handler);
}
.....
.....
}
catch (Exception handlerEx) {
if (logger.isWarnEnabled()) {
logger.warn("Failure while trying to resolve exception [" + ex.getClass().getName() + "]", handlerEx);
}
}
return null;
}
protected ModelAndView handleTypeMismatch(TypeMismatchException ex,
HttpServletRequest request, HttpServletResponse response, @Nullable Object handler) throws IOException {
response.sendError(HttpServletResponse.SC_BAD_REQUEST);
return new ModelAndView();
}
스프링이 내부에서 발생한 예외들을 HTTP 스펙에 맞는 상태코드로 바꿔서 전환해서 처리해준다.
DefaultHandlerExceptionResolver : 스프링 내부 예외 처리