Notice
Recent Posts
Recent Comments
Link
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

개발자되기 프로젝트

[API예외] HandlerExceptionResolver 활용 본문

인프런/[인프런] 스프링 MVC 2

[API예외] HandlerExceptionResolver 활용

Seung__ 2021. 9. 28. 22:45

1.예외를 ExceptionResolver에서 마무리하기


  • 예외가 발생하면 WAS까지 예외가 던져지고, WAS에서 오류 페이지 정보를 찾아서 
  • 다시 /error 를 호출하는 과정은 생각해보면 너무 복잡하다. 
  • ExceptionResolver 를 활용하면 예외가 발생했을 때 이런 복잡한 과정 없이
  • ExceptionResolver에서 문제를 깔끔하게 해결- > BasicErrorController호출하는 등의 절차가 없음.

 

2. UserException


  • 임의의 예외를 만듦 
public class UserException extends RuntimeException{

    public UserException() {
        super();
    }

    public UserException(String message) {
        super(message);
    }

    public UserException(String message, Throwable cause) {
        super(message, cause);
    }

    public UserException(Throwable cause) {
        super(cause);
    }

    protected UserException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
        super(message, cause, enableSuppression, writableStackTrace);
    }
}

 

 

 

3. ExceptionResolver


  • ExceptionResolver에서 Exception처리를 해버리자.
  • response객체세 상태 코드, contentType, Encoding, messageBody에 넣을 내용을 세팅해준다.
  • 이 때 Map타입의 에러 내용을  String으로 변환하기 위해 ObjectMapper 사용
  • 모든 세팅을 마친 후 빈 ModelAndView를 반환하여 WAS에 정상 응답을 내려주자.
  • WAS입장에서는 Exception이 아닌 ModelAndView가 반환되었기 때문에 정상 응답으로 처리 할 것.
@Slf4j
public class UserHandlerExceptionResolver implements HandlerExceptionResolver {

    private final ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {

        try{

            if(ex instanceof UserException){
                log.info("UserException Resolver to 400");
                String acceptHeader = request.getHeader("accept");
                response.setStatus(HttpServletResponse.SC_BAD_REQUEST);

                if("application/json".equals(acceptHeader)){
                    Map<String, Object> errorResult = new HashMap<>();
                    errorResult.put("ex", ex.getClass());
                    errorResult.put("message", ex.getMessage());

                    String result = objectMapper.writeValueAsString(errorResult);

                    response.setContentType("application/json");
                    response.setCharacterEncoding("utf-8");
                    response.getWriter().write(result);

                    return new ModelAndView();
                }else {
                    //text/html
                    return new ModelAndView("error/500");
                }
            }


        }catch (IOException e){
            log.info("resolver ex", ex);

        }

        return null;
    }
}

 

 

 

4. ExceptionResolver 등록


@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {

        resolvers.add(new MyHandlerExceptionResolver());
        resolvers.add(new UserHandlerExceptionResolver());
    }
    
 }

 

 

5. 실행.


  • Accept : application/json

 

 

6. 정리


  • ExceptionResolver 를 사용하면 
  • 컨트롤러에서 예외가 발생해도 ExceptionResolver 에서 예외를 처리해버린다.
  • 즉 예외가 발생해도 서블릿 컨테이너까지 예외가 전달되지 않고, \
  • 스프링 MVC에서 예외 처리가 끝남!
  • 결과적으로 WAS 입장에서는 정상 처리가 된 것이다. 
  • 이렇게 예외를 이곳에서 모두 처리할 수 있다는 것이 핵심이다.
  • 서블릿 컨테이너까지 예외가 올라가면 복잡하고 지저분하게 추가 프로세스가 실행된다. 
    • /error가 호출되어 BasicErrorController호출되고 accept에 맞는 method호출되고 등등
  • 반면에 ExceptionResolver 를 사용하면 예외처리가 상당히 깔끔
    • ExceptionResolver에서 예외처리가 끝나고 이전 처럼 다시 BasicController를 호출하지 않음.
  • ExceptionResolver에서 응답할 data를 넣어두지 않는 경우, BasicErrorHandler에서 대응해야.
  • ExceptionResolver에서 응답할 data를 세팅하는 경우, BasicErrorHandler가 호출될 필요가 없음.
  • 그런데 직접 ExceptionResolver 를 구현하려고 하니 상당히 복잡하다. 

 

7. GitHub : 210928 HandlerExceptionResolver활용


 

GitHub - bsh6463/Exception

Contribute to bsh6463/Exception development by creating an account on GitHub.

github.com

 

Comments