ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • API 예외처리-2
    스프링 2023. 1. 27. 16:20

    API 마다, 각각의 컨트롤러나 예외마다 서로 다른 응답 결과를 출력해야 할 수도 있다.

    예를 들어서 회원과 관련된 API에서 예외가 발생할 때 응답과, 상품과 관련된 API에서 발생하는 예외에 따라 그 결과가 달라질 수 있다.

     

    예외가 발생해서 서블릿을 넘어서 WAS까지 전달되면 HTTP코드는 500이 된다.

    이때 예외외 따랄서 다른 상태코드로 처리하고싶고, 형식을 API마다 다르게 처리하고 싶다면 어떻게 해야할까?

     

     

    HandlerExceptionResolver

    서블릿을 넘어서 WAS까지 예외가 전달되면 status는 500으로 처리된다.
    발생하는 예외에 따라서 400, 404 등등 다른 상태코드도 처리하고 형식을 다르게 하려면 HandlerExceptionResolver를 이용해야 한다.

    HandlerExceptionResolver는 스프링 MVC밖으로 던져진 에외를 해결하고 동작을 해로 정의할 수 있는 방법을 제공한다.

     

     

    WAS에서 DispatcherSevlet이 호촐되면 인터셉터의 preHandle이 호출되고 핸들러 어댑터에서 핸들러를 실행했는데,

    예외가 발생한다.

    이때 postHandler는 호출이 되지 않고 예뢰가 afterCompletion으로 전달된다.

     

     

    요청이 오면 dispatchselvlet으로 가서, prehandler를 호출하여 똑같이 핸들러에서 예외가 발생한다.
    이대 예외가 전달이 되고 postHandler는 호출되지 않는다.
    대신 ExceptionResolver가 있다면 ExceptionResolver가 호출이 된다.
    그리고 예외를 해결하려고 하여 정상동작하려고 시도한다.

     

    HandlerExceptionResolver는 다음과 같이 생겼다.

    public interface HandlerExceptionResolver {
     ModelAndView resolveException(
     HttpServletRequest request, HttpServletResponse response,
     Object handler, Exception ex);
    }

    반환타입으로 ModelAndView를 반환하면 된다.

     

    @Slf4j
    public class MyHandlerExceptionResolver implements HandlerExceptionResolver {
        @Override
        public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
    
            try {
                if (ex instanceof IllegalArgumentException) {
                    log.info("IllegalArgumentException resolver to 400");
                    response.sendError(HttpServletResponse.SC_BAD_REQUEST, ex.getMessage());
                    return new ModelAndView(); 
                }
            } catch (IOException e) {
                log.error("resolver ex", e);            
            }
    
            return null;
        }
    }

    HandlerExceptionResolver를 상속 받아서 다음과 같이 구현하도록 한다.

    예외가 IllegalArgumentException이면 파라미터의 Error의 메시지와 상태코드를 설정하여 이를 ModelAndView를 return시킨다.

    이때 ModelAndView를 빈값으로 넘기면 그냥 정상흐름으로 return시켜서 서블릿 컨테이너로 간다.

    참고로 view를 넣어주면 해댱 view를 랜더링 해준다.

     

    이를 등록시키자.

    설정파일에 다음과 같이 extendHandlerExceptionResolvers를 오버라이드 하자.

    @Override
    public void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {
        resolvers.add(new MyHandlerExceptionResolver());
    }

     

     

     

    다음과 같이 상태 코드를 400으로 변경시킨 것을 확인할 수 있다.

    728x90

    '스프링' 카테고리의 다른 글

    API 예외처리-4 (ExceptionHandler)  (0) 2023.01.28
    API 예외처리-3  (0) 2023.01.27
    API 예외처리-1  (0) 2023.01.26
    OAuth2.0과 JWT적용 - 3  (0) 2023.01.25
    UsernamePasswordAuthenticationFilter  (0) 2023.01.19

    댓글

Designed by Tistory.