스프링 예외 처리와 오류 페이지

jjunhwan.kim·2022년 7월 19일
0

서블릿 오류, 예외 처리

  • 발생한 예외가 전달되어 컨트롤러에서도 처리되지 않고 던져지거나, HttpServletResponse의 sendError 메서드가 호출되면 아래와 같은 흐름으로 진행된다.
컨트롤러 예외 발생 -> 인터셉터 -> 서블릿 -> 필터 -> WAS
컨트롤러 HttpServletResponse의 sendError 메서드 호출 -> 인터셉터 -> 서블릿 -> 필터 -> WAS
  • WAS에서 예외 발생 혹은 response에 sendError 메서드가 호출되었는지 확인하여 설정된 오류 페이지를 찾아 다시 호출한다.
WAS에서 설정된 오류 페이지 요청 -> 필터 -> 서블릿 -> 인터셉터 -> 컨트롤러(오류 페이지를 처리하는 컨트롤러)
  • 결과적으로 오류 또는 예외 발생시 WAS에서 다시 필터-> 서블릿 -> 인터셉터로 호출 흐름이 발생하게 되므로 이 요청이 클라이언트로부터의 요청인지 오류 페이지를 출력하기 위한 내부 요청인지 구분하기 위해 DispatcherType이라는 추가 정보를 제공한다.
  • DispatcherType은 FORWARD, INCLUDE, REQEUST, ASYNC, ERROR 으로 구분된다.
  • HttpServletRequest의 getDispatcherType 메서드를 통해 확인할 수 있다.
  • 필터는 필터 등록시에 DispatcherType에 따라 호출되거나 호출되지 않도록 설정할 수 있다. FilterRegistrationBean을 찾아보자.
  • 인터셉터는 스프링이 제공하는 기능이므로 DispatcherType에 무관하게 항상 호출된다. 대신 인터셉터는 요청 URL 경로에 따라 추가하거나 제외할 수 있으므로 오류 페이지 경로를 excludePathPatterns 메서드에 등록하면 제외할 수 있다.

스프링 부트 오류, 예외 처리

  • 스프링 부트에서는 오류 페이지 설정 등록과 오류 페이지를 처리하는 컨트롤러가 기본적으로 제공된다.(BasicErrorController)
  • 스프링 부트 기본 설정으로 오류 발생시 '/error' 를 오류 페이지로 요청한다.
  • 개발자는 오류 페이지 화면만 등록하면 된다.
  • resources/templates/error 밑에 500.html, 5xx.html, 400.html, 4xx.html 등의 형식으로 오류 페이지를 등록한다.
  • 항상 구체적인 것이 덜 구체적인 것 보다 우선순위가 높다. 따라서 500이 5xx보다 우선순위가 높다.

API 예외 처리

  • 기본적으로 스프링 부트의 BasicErrorController는 클라이언트의 요청의 Accept 헤더 값이 text/html인 경우에는 HTML을 반환하고 그외의 경우에 JSON 데이터를 반환한다.
  • 하지만 BasicErrorController는 HTML 페이지를 제공하는 경우에는 편리하지만 API 응답을 제공하기엔 불편하다. 왜냐하면 반환하는 데이터 형식이 정해져있고, 예외의 종류에 관계없이 상태 코드가 500으로 반환된다.
  • ExceptionResolver를 사용하면 컨트롤러에서 예외가 발생했을 때 WAS까지 전달되기전에 ExceptionResolver에서 예외를 잡아서 JSON 또는 HTML을 반환하도록 처리할 수 있다. 따라서 WAS까지 예외가 전달되고 다시 컨트롤러로 오류 페이지가 요청되는 흐름을 없앨 수 있다.
  • 스프링에서 기본적으로 제공되는 ExceptionResolver들이 있는데 대표적으로 @ExceptionHandler를 처리하는 Resolver와 @ResponseStatus를 처리하는 Resolver가 있다.
    • ExceptionHandlerExceptionResolver
      • @ExceptionHandler 처리
    • ResponseStatusExceptionResolver
      • @ResponseStatus가 달려있는 예외 처리
      • ResponseStatusException 처리
    • DefaultHandlerExceptionResolver
      • 스프링 내부 기본 예외 처리
      • ex) TypeMismatchException
  • @ResponseStatus는 예외 클래스에 선언하여 반환 할 HTTP 상태코드와 메시지를 설정한다.
  • @ExceptionHandler는 메서드에 선언하여 처리하고 싶은 예외를 지정해준다.
  • @ControllerADbice 또는 @RestControllerAdvice를 사용하여 Exception 처리 코드를 컨트롤러 클래스에서 분리할 수 있다.

0개의 댓글