@ControllerAdvice
Spring의 어노테이션
애플리케이션 내의 모든 컨트롤러에 대해 전역적인 “보조(Advice)” 기능을 제공
즉, 하나의 클래스에서 예외 처리, 데이터 바인딩, 모델 속성 추가 등의 공통 기능을 선언해두면, 모든 컨트롤러가 이를 자동으로 상속받아 적용받음주요 기능 및 활용
전역 예외 처리
@ControllerAdvice와 @ExceptionHandler를 조합하면, 특정 예외뿐 아니라 계층 구조에 있는 모든 예외를 포괄적으로 처리할 수 있다 이를 통해 애플리케이션 내에서 발생하는 예외에 대해 일관된 응답을 제공할 수 있다.
@ControllerAdvice public class GlobalExceptionHandler { // 특정 예외에 대한 전역 처리 @ExceptionHandler(ResourceNotFoundException.class) public ResponseEntity<String> handleResourceNotFound(ResourceNotFoundException ex) { // 예외 메시지, 상태 코드 등을 로깅하거나 추가 작업 수행 가능 return ResponseEntity.status(HttpStatus.NOT_FOUND) .body("리소스를 찾을 수 없습니다: " + ex.getMessage()); } // 모든 예외를 포괄하는 핸들러 @ExceptionHandler(Exception.class) public ResponseEntity<String> handleAllExceptions(Exception ex) { // 다양한 예외에 대한 공통 처리 로직 구현 가능 return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) .body("서버 내부 오류가 발생했습니다."); } }흐름: 1. 컨트롤러 내에서 예외가 발생 2. Spring이 먼저 컨트롤러 내의 @ExceptionHandler 메서드를 찾음 3. 만약 해당 컨트롤러에 적절한 핸들러가 없으면, 전역으로 등록된 @ControllerAdvice 내의 핸들러를 순차적으로 탐색 4. 예외의 타입 및 계층 구조에 따라 가장 적합한 메서드가 호출글로벌 데이터 바인딩
@InitBinder 메서드를 사용하면, 컨트롤러의 메서드가 호출되기 전에 공통적으로 적용할 데이터 바인딩 규칙이나 포맷 변환 로직을 정의할 수 있다.
@ControllerAdvice public class GlobalBindingInitializer { @InitBinder public void initBinder(WebDataBinder binder) { // 예: 날짜 포맷 변환 설정 SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); dateFormat.setLenient(false); binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false)); } }요청 파라미터를 컨트롤러 메서드에 바인딩하기 전에 모든 컨트롤러에서 공통적으로 적용할 로직을 미리 등록하여 데이터 변환 및 검증 과정을 일원화 가능ControllerAdvice의 매커니즘
@ControllerAdvice public class ExceptionControllerAdvice { @ExceptionHandler(CustomException.class) public ResponseEntity<String> handleCustomException(CustomException e) { return ResponseEntity.status(e.getStatus().value()).body(e.getMessage()); } }
- 애플리케이션이 시작될 때, Spring은 @ControllerAdvice가 선언된 클래스를 스캔
- 이때 해당 클래스는 전역 어드바이스로 등록되며 각 컨트롤러의 요청 처리 전에 필요한 메서드들이 함께 로딩
- 요청 처리 과정에서 컨트롤러에서 예외가 발생하거나, 바인딩 혹은 모델 설정이 필요한 경우, DispatcherServlet이 우선 전역 어드바이스에서 해당 로직을 검색 후 이를 적용
REST API 개발 시 @RestControllerAdvice
@RestControllerAdvice는 @ControllerAdvice와 동일한 기능을 제공하지만 모든 메서드에 자동으로 @ResponseBody가 적용 이를 통해 JSON이나 XML과 같은 포맷으로 응답을 반환하는 RESTful API 개발에 더욱 적합