(번역) Spring @ControllerAdvice 와 @ExceptionHandler

본 글은 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
2
3
4
5
6
7
8
9
10
11
// @RestController 애노테이션이 선언된 모든 컨트롤러를 대상으로 함
@ControllerAdvice(annotations = RestController.class)
public class AnnotationAdvice {}

// 특정 패키지에 선언되어 있는 모든 컨트롤러를 대상으로 함
@ControllerAdvice("org.example.controllers")
public class BasePackageAdvice {}

// 특정 클래스들을 할당할 수 있는 모든 컨트롤러들을 대상으로 함
@ControllerAdvice(assignableTypes = {ControllerInterface.class, AbstractController.class})
public class AssignableTypesAdvice {}

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
2
3
4
5
6
7
8
9
10
11
12
@Controller
public class SimpleController {

// @RequestMapping methods omitted ...

@ExceptionHandler(IOException.class)
public ResponseEntity<String> handleIOException(IOException ex) {
// prepare responseEntity
return responseEntity;
}

}

@ExceptionHandler 값은 예외 타입의 배열로 설정될 수 있다. 만약 목록에 있는 타입의 하나와 일치하는 예외가 던져진다면, @ExceptionHandler 메서드가 실행될 것이다. 만약 애노테이션 값이 설정되어 있지 않으면 메소드의 인자로 전달되는 예외 타입이 사용되어 진다.
@RequestMapping 애노테이션이 선언된 기본적인 컨트롤러들과 같이, @ExceptionHandler 메서드의 메서드 인자와 반환 값은 유연성을 가진다. 예를 들어 HttpServletRequest는 서블릿 환경에서 사용되어 질 수 있고, PortletRequest는 포틀릿 환경에서 사용되어 질 수 있다. 반환 타입 또한 view 이름으로 변환되는 String, ModelAndView 객체, ResponseEntity 가 될 수 있으며, 메시지 컨버터에 의해서 변환되고 응답 스트림으로 쓰여지는 메서드 응답을 획득하기 위해서 @ResponseBody 을 추가할 수 있다.

분산 트랜잭션 - 큰힘에는 큰 책임이 따른다 [유승기, MongoDB] 책임의 자율성이 협력의 품질을 결정한다

Comments

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×