[Spring] 예외 처리와 오류 페이지

Manx·2022년 6월 20일
0

spring

목록 보기
17/24

인프런 '스프링 MVC 2편' - 김영한님의 강의 내용

Exception (예외)

웹 애플리케이션
사용자 요청별로 별도의 쓰레드가 할당되고, 서블릿 컨테이너 안에서 실행된다.

애플리케이션에서 예외를 잡지 못하고, 서블릿 밖으로 까지 예외가 전달되면 WAS까지 예외가 전달된다.

WAS <- 필터 <- 서블릿 <- 인터셉터 <- 컨트롤러(예외발생)

response.sendError()를 호출하면, WAS에서 클라이언트에게 응답 전에 response에 sendError()가 호출되었는지 확인 후, 오류가 발생함을 인지하고 오류 페이지를 보여주게 된다.

흐름

  1. 컨트롤러에서 예외 발생

    WAS(sendError 호출 확인) <- 필터 <- 서블릿 <- 인터셉터 <- 컨트롤러(예외발생, response.sendError())

  2. 오류 페이지 요청

    WAS /error-page/500 다시 요청 -> 필터 -> 서블릿 -> 인터셉터 -> 컨트롤러(/errorpage/
    500) -> View

여기에서 오류 페이지를 요청할 때 필터 인터셉터가 다시 호출되는 것이 매우 비효율적이기 때문에,
클라이언트로 부터 발생한 요청인지, 오류 페이지를 출력하기 위한 내부 요청인지 구분할 수 있어야 한다.
이를 해결하기 위해 서블릿은 DispatcherType이라는 추가 정보를 제공해준다.

  • 고객이 처음 요청했을 경우 : dispatcherType=REQUEST
  • 내부 호출 : dispatcherType=ERROR

필터에 setDispatcherTypes의 파라미터로 DispatcherType.REQUEST만 사용하면 ERROR에 대해서는 필터가 호출되지 않는다.

@Configuration
public class WebConfig implements WebMvcConfigurer {
	@Bean
	public FilterRegistrationBean logFilter() {
		FilterRegistrationBean<Filter> filterRegistrationBean = new FilterRegistrationBean<>();
		filterRegistrationBean.setFilter(new LogFilter());
		filterRegistrationBean.setOrder(1);
		filterRegistrationBean.addUrlPatterns("/*");
        
        // 이 부분
		filterRegistrationBean.setDispatcherTypes(DispatcherType.REQUEST, DispatcherType.ERROR);
        
		return filterRegistrationBean;
}
}

인터셉터 호출 방지
인터셉터는 서블릿이 제공하는 기능이 아닌 스프링이 제공하는 기능이라 DispatcherType과는 무관하게 항상 호출된다.

excludePathPatterns를 이용해 오류 페이지 경로를 제외시키면 된다.

@Override
public void addInterceptors(InterceptorRegistry registry) {
	registry.addInterceptor(new LogInterceptor())
			.order(1)
			.addPathPatterns("/**")
            
            //오류 페이지 경로 ("/error")
			.excludePathPatterns( "/css/**", "/*.ico", "/error", "/error-page/**");
}

스프링 부트 제공

스프링 부트가 이런 과정을 모두 기본으로 제공해준다.
따라서 개발자는 다음 경로에 오류 페이지들만 넣어두면 된다.

뷰 템플릿

  • resources/templates/error/500.html
  • resources/templates/error/5xx.html

정적 리소스(static, public)

  • resources/static/error/400.html
  • resources/static/error/4xx.html
profile
백엔드 개발자

0개의 댓글