파라미터 유효성 검사 기능 개발 중, HttpMessageNotReadableException
을 핸들링 하는 방법을 찾던 중 HandlerExceptionResolver
을 구현하게 되었는데, 관련 내용을 정리해 두려고 한다. 1편은 예외처리와 오류 페이지 , 2편은 API 예외처리 방식을 포스팅 할 예정이다.
Exception
(예외)response.sendError(HTTP 상태 코드, 오류 메시지)
WAS
가 이 예외를 받게 된다.WAS
는 미리 만들어둔 예외 페이지가 존재한다면 그 페이지 URL로 다시 요청 메세지를 보내고, 그 외에는 톰캣이 기본으로 제공하는 오류 페이지에 HTTP
상태 코드 500
으로 응답을 보낸다.HttpServletResponse
가 제공하는 sendError
라는 메서드를 사용할 수 있다.import org.springframework.boot.web.server.ConfigurableWebServerFactory;
import org.springframework.boot.web.server.ErrorPage;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
@Component
public class WebServerCustomizer implements WebServerFactoryCustomizer<ConfigurableWebServerFactory> {
@Override
public void customize(ConfigurableWebServerFactory factory) {
ErrorPage errorPage404 = new ErrorPage(HttpStatus.NOT_FOUND, "/error-page/404");
ErrorPage errorPage500 = new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, "/error-page/500");
ErrorPage errorPageEx = new ErrorPage(RuntimeException.class, "/error-page/500");
factory.addErrorPages(errorPage404, errorPage500, errorPageEx);
}
}
WebServerFactoryCustomizer
로 오류 페이지를 등록할 수 있다.ErrorPage errorPage = new ErrorPage(Http 상태코드, 오류페이지 경로)
: response.sendError()
에 설정한 상태코드를 받는다.ErrorPage errorPage = new ErrorPage(Exception.class, 오류페이지 경로)
: 발생한 예외 및 그 자식 예외 클래스를 받는다.✅ 스프링 부트는
whitelabel
이라는 자체 오류페이지를 제공하기 때문에 톰캣이 제공하는 오류 페이지를 보려면resource/application.properties
에 아래 코드를 추가시켜줘야한다.server.error.whitelabel.enabled=false
WAS
는 지정해둔 URL로 일반적인 페이지 요청 신호를 보내기 때문에 이를 받을 컨트롤러가 필요하다.import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Slf4j
@Controller
public class ErrorPageController {
@RequestMapping("/error-page/404")
public String errorPage404(HttpServletRequest request, HttpServletResponse response) {
log.info("errorPage 404");
return "error-page/404";
}
@RequestMapping("/error-page/500")
public String errorPage500(HttpServletRequest request, HttpServletResponse response) {
log.info("errorPage 500");
return "error-page/500";
}
}
WAS
까지 전파되고, 에러 페이지를 출력하기 위해 WAS
가 다시 에러 페이지 URL을 요청하는 과정에서 매번 필터와 인터셉터가 호출된다. (비효율적)DispatcherType
이라는 추가 정보를 제공하여, 클라이언트로 부터 발생한 정상 요청인지, 아니면 오류 페이지를 출력하기 위한 내부 요청인지 구분할 수 있게 해준다. @Bean
public FilterRegistrationBean logFilter() {
FilterRegistrationBean<Filter> filterRegistrationBean = new FilterRegistrationBean<Filter>();
filterRegistrationBean.setFilter(new LogFilter());
filterRegistrationBean.setOrder(1);
filterRegistrationBean.addUrlPatterns("/*");
filterRegistrationBean.setDispatcherTypes(DispatcherType.REQUEST, DispatcherType.ERROR);
return filterRegistrationBean;
}
스프링 부트 API 예외 처리 [2] HandlerExceptionResolver
ExceptionResolver를 이용한 API예외 처리
HandlerExceptionResolver - API 예외처리
API 예외 처리 (1) - MediaType, ExceptionResolver
스프링 예외 처리와 오류 페이지
[Spring] 예외 처리(BasicErrorController, HandlerExceptionResolver)
Servlet - 예외처리와 오류 페이지 (Exception)
[Spring] 톰캣(servlet) 에러페이지가 아닌 whitelabel Error Page가 뜨는 이유