본문 바로가기
Backend, Server/Spring MVC

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

by ggyongi 2022. 4. 29.
반응형

스프링이 아닌 순수 서블릿 컨테이너의 예외 처리 방법


- 서블릿은 2가지 방식의 예외 처리를 지원
1. Exception(예외)
2. response.sendError(HTTP 상태코드, 오류 메시지)

- 예외의 전달 과정
1. Exception
WAS(여기까지 전파) <- 필터 <- 서블릿 <- 인터셉터 <- 컨트롤러(예외발생)


2. sendError
WAS(sendError 호출 기록 확인) <- 필터 <- 서블릿 <- 인터셉터 <- 컨트롤러(sendError)


- 오류 화면 제공
순서는 1. 오류 페이지 등록, 2. 오류 처리 컨트롤러 등록, 3. 오류 처리 뷰 등록

1. 오류 페이지 등록

@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);
    }
}

2. 오류 처리 컨트롤러 등록

@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";
    }

3. 오류 처리 뷰

/templates/error-page/404.html에 파일을 만들면 된다.

 

 

 

- 예외 발생과 오류 페이지 요청 흐름

1. WAS(여기까지 전파) <- 필터 <- 서블릿 <- 인터셉터 <- 컨트롤러(예외발생)

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

 

오류가 발생하면 오류 페이지를 출력하기 위해 WAS 내부에서 다시 한번 호출이 발생한다.

이때 필터, 서블릿, 인터셉터도 모두 다시 호출된다. 그런데 로그인 인증 체크 같은 경우를 생각해보면, 이미 한번 필터나, 인터셉터에서 로그인 체크를 완료했다. 따라서 서버 내부에서 오류 페이지를 호출한다고 해서 해당 필터나 인터셉트가 한번 더 호출되는 것은 매우 비효율적이다.

 

- 필터의 중복 호출 막기

: DispatcherType을 설정해준다.

DispatcherType.REQUEST만 적용하면 클라이언트 요청의 경우에만 필터가 적용되고

오류 페이지 요청에는 필터가 적용되지 않는다.

@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;
    }
}

- 인터셉터 중복 호출 막기

: 경로 지정을 통해 오류 페이지를 제외시킨다.


@Configuration
public class WebConfig implements WebMvcConfigurer {

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

}

 

 

서블릿에서는 이런 방식으로 처리를 하고.. ok, 그럼 스프링에서는? => 매우매우 간단하게 처리된다.

 

스프링부트 오류 페이지 처리

스프링부트는 ErrorPage를 자동으로 등록하고 /error 경로로 기본 오류페이지를 설정한다.

그리고 BasicErrorController라는 스프링 컨트롤러를 자동으로 등록한다. 이 컨트롤러는 ErrorPage에서 등록한 /error를 매핑해서 처리한다.

 

BasicErrorController 의 처리 순서(우선순위)

1. 뷰 템플릿

resources/templates/error/500.html

resources/templates/error/5xx.html

 

2. 정적 리소스( static , public )

resources/static/error/400.html

resources/static/error/404.html

resources/static/error/4xx.html

 

3. 적용 대상이 없을 때 뷰 이름( error )

resources/templates/error.html

 

 

따라서 해당 경로 위치에 HTTP 상태 코드 이름의 뷰 파일을 넣어두면 된다 => 이게 전부다. 매우 간단!

예시)

resources/templates/error/4xx.html

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
  <meta charset="utf-8">
</head>
<body>
<div class="container" style="max-width: 600px">
  <div class="py-5 text-center">
    <h2>4xx 오류 화면 스프링 부트 제공</h2>
  </div>
  <div>
    <p>오류 화면 입니다.</p>
  </div>
  <hr class="my-4">
</div> <!-- /container -->
</body>
</html>

 

----------------------------------------------
참고 : 인프런 김영한님 강의(스프링 MVC 2편 - 백엔드 웹 개발 활용 기술)

 

비전공자 네카라 신입 취업 노하우

시행착오 끝에 얻어낸 취업 노하우가 모두 담긴 전자책!

kmong.com

댓글