본 글은 Spring 4.3.12의 레퍼런스 문서 에서 @ControllerAdvice
와 @ExceptionHandler
관련 부분을 번역한 글입니다. 부족한 해석이 있다면 피드백 부탁드리겠습니다.
Advising controllers with @ControllerAdvice and @RestControllerAdvice
@ControllerAdvice
애노테이션은 클래스패스 스캐닝을 통해서 자동으로 검출되어지는 구현 클래스를 허용하는 컴포넌트 애노테이션이다. MVC 네임스페이스와 MVC 자바 설정을 사용하면 자동으로 활성화된다.@ControllerAdvice
선언이 되어 있는 클래스는 @ExceptionHandler
와 @InitBinder
, @ModelAttribute
가 선언된 메소드들을 포함한다. 그리고 이 메소드들은 자신들이 선언되어 있는 컨트롤러 계층 구조와는 반대 방향으로 @RequestMapping
메소드들에 적용될 것이다.
기본적으로 @RestControllerAdvice
는 @ExceptionHandler
메소드가 @ResponseBody
로 결과를 반환하고자 하는 곳에 대신 사용할 수 있다.@ControllerAdvice
와 @RestControllerAdvice
둘 다 컨트롤러들 중에서 일부만 대상으로 삼을 수 있다.
1 | // @RestController 애노테이션이 선언된 모든 컨트롤러를 대상으로 함 |
HandlerExceptionResolver
Spring HandlerExceptionResolver
구현체들은 컨트롤러가 실행되는 동안 발생하는 예상하지 못한 예외들을 다룬다. HandlerExceptionResolver
는 웹 애플리케이션 지시자인 web.xml
에 정의할 수 있는 예외 매핑과 유사하다. 그러나 그것들은 더 유연한 방법을 제공한다. 예를 들어 그것들은 예외가 던져졌을 때 어떤 핸들러가 실행되는 중인지에 대한 정보를 제공한다. 더욱이 예외들을 다루는 프로그래마틱한 방법들은 요청이 다른 URL로 전달되기 전에 더 많은 선택지를 제공한다.
resolveException(Exception, Handler)
메서드를 구현하고 ModelAndView
를 반환하는 유일한 방법인 HandlerExceptionResolver
인터페이스를 구현하는 것 외에도, 제공되는 SimpleMappingExceptionResolver
를 사용하거나 @ExceptionHanlder
메서드를 사용할 수 있다. SimpleMappingExceptionResolver
는 발생할 수 있는 예외의 클래스 명을 획득고 이것은 view 이름과 매핑할 수 있게 해준다. 이것은 예외를 Servlet API가 제공하는 기능과 매팽하는 것과 기능적으로 동일하다. 그리고 이것은 또한 다른 핸들러의 예외에 대한 더 정교한 매핑을 구현할 수 있다. 반면에 @ExceptionHandler
애노테이션은 예외를 다루기 위해 실행되어지는 메서드 위에서 사용되어 질 수 있다. 이 메서드들은 @Controller 안에서 지역적으로 선언되어 진다. @ControllerAdvice
클래스 안에서 정의될 때는 다수의 @Controller
에 적용할 수 있다.
@ExceptionHandler
HandlerExceptionResolver
인터페이스와 SimpleMappingExceptionResolver
구현체들은 예외들과 특정 view들을 선택적인 자바 로직에 따라서 선언적으로 매핑하는 것을 허용한다. 그러나 특정한 경우에, 특히 view resolution 보다는 @ResponseBody
메서드들의 경우에는 응답의 몸체에 상태를 직접 설정하거나 선택적으로 에러 컨텐츠를 작성하는 것이 더 편리할 수도 있다.
컨트롤러 내에서 @RequestMapping
메소드에 @ExceptionHandler
를 선언할 수 있다. 또한 @ControllerAdvice
클래스 안에서 @ExceptionHandler
를 선언하여 여러 컨트롤러의 예외를 처리 할 수 있다. 아래는 @ExceptionHanderl
를 컨트롤러 내에서 지역적으로 사용하는 예제이다.
1 | @Controller |
@ExceptionHandler
값은 예외 타입의 배열로 설정될 수 있다. 만약 목록에 있는 타입의 하나와 일치하는 예외가 던져진다면, @ExceptionHandler
메서드가 실행될 것이다. 만약 애노테이션 값이 설정되어 있지 않으면 메소드의 인자로 전달되는 예외 타입이 사용되어 진다.@RequestMapping
애노테이션이 선언된 기본적인 컨트롤러들과 같이, @ExceptionHandler
메서드의 메서드 인자와 반환 값은 유연성을 가진다. 예를 들어 HttpServletRequest
는 서블릿 환경에서 사용되어 질 수 있고, PortletRequest
는 포틀릿 환경에서 사용되어 질 수 있다. 반환 타입 또한 view 이름으로 변환되는 String
, ModelAndView
객체, ResponseEntity
가 될 수 있으며, 메시지 컨버터에 의해서 변환되고 응답 스트림으로 쓰여지는 메서드 응답을 획득하기 위해서 @ResponseBody
을 추가할 수 있다.
Comments