@ControllerAdvice는 Spring MVC에서 전역적으로 예외를 처리하거나, 컨트롤러에서 공통적으로 적용할 수 있는 기능을 정의할 때 사용하는 어노테이션이다. 이를 활용하면 개별 컨트롤러마다 중복된 예외 처리 로직을 작성할 필요 없이 중앙 집중적으로 예외 처리를 할 수 있다.
@ExceptionHandler)@InitBinder)@ModelAttribute)다음은 @ControllerAdvice를 사용하여 예외를 전역적으로 처리하는 방법이다.
@RestControllerAdvice // @ControllerAdvice + @ResponseBody
public class GlobalExceptionHandler {
@ExceptionHandler(IllegalArgumentException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public Map<String, String> handleIllegalArgumentException(IllegalArgumentException ex) {
Map<String, String> errorResponse = new HashMap<>();
errorResponse.put("error", ex.getMessage());
return errorResponse;
}
}
@RestControllerAdvice는 @ControllerAdvice와 @ResponseBody를 합친 것.@ExceptionHandler(IllegalArgumentException.class): IllegalArgumentException 예외가 발생하면 이 메서드가 실행됨.@ResponseStatus(HttpStatus.BAD_REQUEST): HTTP 상태 코드를 400 (Bad Request)로 설정.@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(IllegalArgumentException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public String handleIllegalArgumentException(IllegalArgumentException ex) {
return ex.getMessage();
}
@ExceptionHandler(NullPointerException.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public String handleNullPointerException(NullPointerException ex) {
return "서버 내부 오류 발생";
}
}
IllegalArgumentException은 400 오류를 반환하고,NullPointerException이 발생하면 500 (Internal Server Error) 상태를 반환.ResponseEntity 활용 예외 처리@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(RuntimeException.class)
public ResponseEntity<Map<String, String>> handleRuntimeException(RuntimeException ex) {
Map<String, String> errorResponse = new HashMap<>();
errorResponse.put("error", ex.getMessage());
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorResponse);
}
}
ResponseEntity를 활용하면 HTTP 상태 코드와 응답 값을 유연하게 설정할 수 있음.모든 컨트롤러에서 공통적으로 사용할 모델 속성을 정의할 수 있다.
@ControllerAdvice
public class GlobalControllerAdvice {
@ModelAttribute("appName")
public String getAppName() {
return "My Spring Application";
}
}
appName이라는 속성을 사용할 수 있게 된다.@InitBinder 사용 예제@ControllerAdvice
public class GlobalBindingAdvice {
@InitBinder
public void initBinder(WebDataBinder binder) {
binder.registerCustomEditor(LocalDate.class, new PropertyEditorSupport() {
@Override
public void setAsText(String text) {
setValue(LocalDate.parse(text, DateTimeFormatter.ofPattern("yyyy-MM-dd")));
}
});
}
}
LocalDate 파라미터가 들어올 때 "yyyy-MM-dd" 형식으로 변환되도록 설정.| 기능 | 어노테이션 | 설명 |
|---|---|---|
| 전역 예외 처리 | @ExceptionHandler | 특정 예외 발생 시 처리 |
| 전역 데이터 바인딩 | @InitBinder | 요청 데이터를 변환 |
| 전역 모델 속성 설정 | @ModelAttribute | 모든 컨트롤러에서 공통으로 사용할 데이터 설정 |
@ControllerAdvice를 사용하면 컨트롤러 코드의 중복을 줄이고, 예외 처리와 설정을 일괄적으로 관리할 수 있어 유지보수성이 향상된다.