본문 바로가기

스프링/Spring MVC

(14)
[API 예외 처리하기] @ExceptionHandler, @ControllerAdvice를 사용한 예외 처리 HTML 화면 오류 vs API 오류 웹 브라우저에 HTML 화면을 제공할 때는 오류가 발생하면 BasicErrorController 를 사용하는게 편합니다. 이때는 단순히 5xx, 4xx 관련된 오류 화면을 보여주면 됩니다. BasicErrorController 는 이런 메커니즘을 모두 구현해두었습니다. BasicErrorController 를 사용하거나 HandlerExceptionResolver 를 직접 구현하는 방식으로 API 예외를 다루기는 쉽지 않습니다. API 예외처리의 어려운 점 HandlerExceptionResolver는 ModelAndView를 반환해야 합니다. 이것은 API 응답에는 필요하지 않습니다. API 응답을 위해서 HttpServletResponse에 직접 응답 데이터를 넣..
[API 예외 처리] 스프링이 제공하는 ExceptionResolver (ResponseStatus, DefaultHandler) 스프링 부트가 기본으로 제공하는 ExceptionResolver는 다음과 같습니다. HandlerExceptionResolverComposite 에 다음 순서로 등록됩니다. 1. ExceptionHandlerExceptionResolver 2. ResponseStatusExceptionResolver 3. DefaultHandlerExceptionResolver 우선순위가 가장 낮습니다. ExceptionHandlerExceptionResolver @ExceptionHandler을 처리한다. API 예외 처리는 대부분 이 기능으로 해결한다. 다음 글에서 다루겠습니다. ResponseStatusExceptionResolver HTTP 상태 코드를 지정해준다. 예) @ResponseStatus(value =..
[API 예외 처리] - HandlerExceptionResolver 사용하기 서버에서 예외가 발생하고, 서블릿을 넘어 WAS까지 예외가 전달되면 HTTP 상태 코드가 500으로 처리됩니다. 발생하는 예외에 따라서 400, 404 등등 다른 상태 코드도 처리하고 싶은 경우 어떻게 하면 될까요? 오류 메시지, 형식등을 API마다 다르게 처리하고 싶으면 어떻게 하면 될까요? 위와 같은 목적을 위해서 HandlerExceptionResolver를 사용하면 처리 가능합니다. 상태 코드 변환 상황: IllegalArgumentException 을 처리하지 못해서 컨트롤러 밖으로 넘어가는 일이 발생하면 HTTP 상태 코드를 400으로 처리하고 싶습니다. @GetMapping("/api/members/{id}") public MemberDto getMember(@PathVariable("id"..
[API 예외 처리] 스프링부트 기본 오류처리 방법 지금부터 API의 경우 어떻게 예외 처리를 하면 좋은지 알아보겠습니다. 먼저 API 예외 상황 서블릿 오류 페이지 방식을 사용해보겠습니다. 서블릿 오류 페이지로 방식 @Component public class WebServerCustomizer implements WebServerFactoryCustomizer { @Override public void customize(ConfigurableWebServerFactory factory) { ErrorPage errorPage404 = new ErrorPage(HttpStatus.NOT_FOUND, "/error-page/404"); ErrorPage errorPage500 = new ErrorPage(HttpStatus.INTERNAL_SERVER_ER..
스프링 부트를 사용해 예외 처리 페이지 제공하기 서블릿만으로 예외 처리 페이지를 만들기 위해서 다음과 같은 복잡한 과정이 필요합니다. WebServerCustomizer를 만들기 예외 종류에 따라서 ErrorPage를 추가하기 예외 처리용 컨트롤러 ErrorPageController를 만들기 스프링 부트는 이런 과정을 모두 기본으로 제공합니다. ErrorPage를 자동으로 등록한다. 이때 /error라는 경로로 기본 오류 페이지를 설정합니다. new ErrorPage("/error") , 상태코드와 예외를 설정하지 않으면 기본 오류 페이지로 사용됩니다. 서블릿 밖으로 예외가 발생하거나, response.sendError(...) 가 호출되면 모든 오류는 /error를 호출하게 됩니다. BasicErrorController 라는 스프링 컨트롤러를 자동으..
서블릿으로 예외처리하기 - 필터, 인터셉터 그리고 DispatchType 예외 발생과 오류 페이지 요청 흐름 1. WAS(여기까지 전파) 컨트롤러(/errorpage/500) -> View 오류가 발생하면 오류 페이지를 출력하기 위해 WAS 내부에서 다시 한번 호출이 발생합니다. 이때 서버 내부에서 로그인 체크 기능을 담당하는 필터나 인터셉트가 한번 더 호출되는 것은 매우 비효율적입니다. 결국 클라이언트로부터 발생한 정상 요청인지, 아니면 오류 페이지를 출력하기 위한 내부 요청인지 구분할 수 있어야 합니다. 서블릿은 이런 문제를 해결하기 위해 DispatcherType이라는 추가 정보를 제공합니다. DispatcherType 필터는 이런 경우를 위해서 dispatcherTypes라는 옵션을 제공합니다. request.getDispatcherType() 오류 페이지에서 disp..
서블릿으로 예외 처리하기 스프링이 아닌 순수 서블릿 컨테이너는 예외를 어떻게 처리하는지 알아보겠습니다. 그래야 스프링 개발 중에 문제가 발생했을 경우 어디를 수정해야 할지 알 수 있기 때문입니다. 서블릿은 다음 2가지 방식으로 예외 처리를 지원합니다. Exception (예외) response.sendError(HTTP 상태 코드, 오류 메시지) 서블릿에서 예외 처리하는 방식 Exception(예외) 자바 직접 실행 자바의 메인 메서드를 직접 실행하는 경우 main이라는 이름의 쓰레드가 실행됩니다. 실행 도중에 예외를 잡지 못하고 처음 실행한 main() 메서드를 넘어서 예외가 던져지면, 예외 정보를 남기고 해당 스레드는 종료됩니다. 웹 애플리케이션 웹 애플리케이션은 사용자 요청별로 별도의 스레드가 할당되고, 서블릿 컨테이너 안..
스프링 인터셉터에 ArgumentResolver 활용하기 지난번에 스프링 인터셉터로 로그인 인증을 구현했고, ArgumentResolver를 사용해 더 간단하게 구현하는 방법을 알아볼 예정입니다. 기존에 @SessionAttribute를 세션을 검증한 기능 @GetMapping("/") public String home(@SessionAttribute(name = SessionConst.LOGIN_MEMBER, required = false) Member loginMember, Model model) { // 세션에 회원 데이터가 없으면 home if (loginMember == null) { return "home"; } model.addAttribute("member", loginMember); return "loginHome"; } ArgumentReso..