Spring MVC/03.예외 처리

[spring 예외 처리] 03.프로그래밍을 통한 예외 처리 2

  • -

이전 포스트에서 @ControllerAdvice를 통한 예외 처리에 대해서 살펴보았다. 이번 포스트에서는 SpringBoot에서 특화된 처리방법을 살펴보자.

 

 

SpringBoot에서 /error에 대한 처리를 담당하는 @Controller는 BasicErrorController이다.  이 녀석의 핵심되는 코드만 잠깐 살펴보자.

@Controller // ${server.error.path} 또는 ${error.path} 또는 /error 요청에 대해 처리 @RequestMapping("${server.error.path:${error.path:/error}}") public class BasicErrorController extends AbstractErrorController { // 일반 HTTP 요청이 왔을 때의 처리 @RequestMapping(produces = MediaType.TEXT_HTML_VALUE) public ModelAndView errorHtml(HttpServletRequest request, HttpServletResponse response) { HttpStatus status = getStatus(request); Map<String, Object> model = Collections .unmodifiableMap(getErrorAttributes(request, getErrorAttributeOptions(request, MediaType.TEXT_HTML))); response.setStatus(status.value()); ModelAndView modelAndView = resolveErrorView(request, response, status, model); return (modelAndView != null) ? modelAndView : new ModelAndView("error", model); } // errorHtml에서 처리하지 않는 즉 ajax 요청에 대해 처리 @RequestMapping public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) { HttpStatus status = getStatus(request); if (status == HttpStatus.NO_CONTENT) { return new ResponseEntity<>(status); } Map<String, Object> body = getErrorAttributes(request, getErrorAttributeOptions(request, MediaType.ALL)); return new ResponseEntity<>(body, status); } }

주석에 적힌바대로 BasicErrorController는 /error 요청에 대해서 일반 http 요청(errorHtml)과 ajax 요청(error)을 구분해서 처리하고 있다. 여기에 추가로 처리하고 싶은 내용이 있다면 BasicErrorController를 상속 받아서 위 두 개의 메서드를 재정의 해주면 된다.

 

이제 BasicErrorController를 확장해서 사용자 정의 ErrorController를 작성해보자.

@Controller @Slf4j public class MyErrorController extends BasicErrorController { public MyErrorController(ErrorAttributes errorAttributes, ServerProperties serverProperties, List<ErrorViewResolver> errorViewResolvers) { super(errorAttributes, serverProperties.getError(), errorViewResolvers); } @Override public ModelAndView errorHtml(HttpServletRequest request, HttpServletResponse response) { ModelAndView mnv = super.errorHtml(request, response); // 부가적으로 필요한 작업 log.debug("model: {}", mnv.getModel()); log.debug("view: {}", mnv.getViewName()); HttpStatus hs = getStatus(request); switch (hs) { case UNAUTHORIZED: mnv.setViewName("/error/401"); break; case NOT_ACCEPTABLE: mnv.setViewName("/error/406"); break; ... default: mnv.setViewName("/error/500"); break; } return mnv; } @Override public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) { ResponseEntity<Map<String, Object>> entity = super.error(request); // 부가적으로 필요한 작업 return entity; } }

 

@ControllerAdvice가 사실 예외 처리를 전담하는 녀석도 아니고 일반 요청인지 ajax요청인지 직접 판단해서 처리해야했던 것에 비해 훨씬 깔끔해졌다.

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.