@ControllerAdvice를 사용한 전역 예외 처리
@ExceptionHandler와 @ControllerAdvice로 모든 컨트롤러의 예외 처리를 중앙화합니다.
@ControllerAdvice를 사용한 전역 예외 처리은(는) CoddyKit의 무료 Java Academy 강의입니다. 이것은 4개 중 3번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 Java Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. Java Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
전역 처리가 없을 때의 문제
전역 예외 처리가 없으면 모든 컨트롤러 메서드에 try-catch 블록이 필요하고, 오류 응답 생성 코드가 중복되며, 예외 세부 정보가 클라이언트에 노출됩니다.
@ControllerAdvice와 @RestControllerAdvice
@ControllerAdvice는 전역 예외 처리기 클래스를 정의합니다. @RestControllerAdvice는 @ResponseBody를 추가하므로 모든 처리기 메서드가 자동으로 JSON을 반환합니다.
@RestControllerAdvice
public class GlobalExceptionHandler {
// @ExceptionHandler methods go here
}@ExceptionHandler 메서드
메서드에 @ExceptionHandler(ExceptionType.class)를 지정하세요. Spring은 해당 유형과 그 하위 유형의 예외를 이 메서드로 전달합니다. 적절한 상태를 포함한 ResponseEntity를 반환하세요.
@ExceptionHandler(ResourceNotFoundException.class)
public ResponseEntity<ErrorResponse> handleNotFound(ResourceNotFoundException ex) {
return ResponseEntity.status(HttpStatus.NOT_FOUND)
.body(new ErrorResponse("NOT_FOUND", ex.getMessage()));
}여러 예외 유형 처리하기
하나의 처리기에 여러 예외 유형을 나열하거나 공통 기본 클래스를 사용하세요. Spring은 사용 가능한 처리기 중 가장 구체적인 처리기를 선택합니다.
@ExceptionHandler({IllegalArgumentException.class, IllegalStateException.class})
public ResponseEntity<ErrorResponse> handleBadRequest(RuntimeException ex) {
return ResponseEntity.badRequest()
.body(new ErrorResponse("BAD_REQUEST", ex.getMessage()));
}검증 오류 처리하기
MethodArgumentNotValidException을 처리해 @Valid로 검증된 요청 본문에서 필드 수준 오류를 추출하세요.
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<Map<String, Object>> handleValidation(MethodArgumentNotValidException ex) {
Map<String, String> fieldErrors = new LinkedHashMap<>();
ex.getBindingResult().getFieldErrors().forEach(e ->
fieldErrors.put(e.getField(), e.getDefaultMessage()));
return ResponseEntity.badRequest()
.body(Map.of("errors", fieldErrors, "status", 400));
}제약 조건 위반 처리하기
서비스 계층에서 @Validated로 메서드 매개변수를 검증하면 ConstraintViolationException이 발생합니다. MVC 검증 오류와 별도로 처리하세요.
@ExceptionHandler(ConstraintViolationException.class)
public ResponseEntity<Map<String, String>> handleConstraint(ConstraintViolationException ex) {
Map<String, String> errors = new LinkedHashMap<>();
ex.getConstraintViolations().forEach(v ->
errors.put(v.getPropertyPath().toString(), v.getMessage()));
return ResponseEntity.badRequest().body(errors);
}HttpServletRequest에 접근하기
요청 세부 정보(URL, 메서드, 헤더)를 가져오려면 매개변수로 HttpServletRequest를 추가하세요. 이 정보는 기록하거나 오류 응답에 포함할 수 있습니다.
@ExceptionHandler(Exception.class)
public ResponseEntity<ErrorResponse> handleAll(Exception ex, HttpServletRequest req) {
log.error("Unhandled error on {} {}", req.getMethod(), req.getRequestURI(), ex);
return ResponseEntity.internalServerError()
.body(new ErrorResponse("INTERNAL_ERROR", "Unexpected error"));
}예외 클래스의 @ResponseStatus
사용자 지정 예외 클래스에 @ResponseStatus를 지정하면 처리기 메서드 없이 HTTP 상태를 자동으로 설정할 수 있습니다. 단순한 경우에 적합합니다.
@ResponseStatus(HttpStatus.NOT_FOUND)
public class ResourceNotFoundException extends RuntimeException {
public ResourceNotFoundException(String msg) { super(msg); }
}@ControllerAdvice 범위 지정하기
@ControllerAdvice의 속성을 사용해 특정 패키지, 애너테이션 또는 기본 클래스에만 조언 기능을 제한할 수 있습니다.
@RestControllerAdvice(basePackages = "com.example.api")
public class ApiExceptionHandler { ... }
@RestControllerAdvice(assignableTypes = {UserController.class, OrderController.class})
public class SpecificHandler { ... }예외 처리기에서 기록하기
예외를 적절한 수준으로 기록하세요. 사용자 오류(4xx)는 WARN으로, 예상하지 못한 오류(5xx)는 전체 스택 추적과 함께 ERROR로 기록합니다.
@ExceptionHandler(Exception.class)
public ResponseEntity<ErrorResponse> handleAll(Exception ex, HttpServletRequest req) {
if (ex instanceof BusinessException) log.warn("Business error: {}", ex.getMessage());
else log.error("Unexpected error on {}", req.getRequestURI(), ex);
return ...
}예외 처리기 우선순위
Spring은 가장 구체적인 처리기를 선택합니다. ResourceNotFoundException extends RuntimeException인 경우 ResourceNotFoundException용 처리기가 RuntimeException용 처리기보다 우선합니다.
빠른 확인
특정 예외 유형을 전역적으로 처리하도록 메서드를 표시하는 어노테이션은 무엇인가요?
복습
@RestControllerAdvice와 @ExceptionHandler를 사용하여 오류 처리를 중앙화합니다. 일관된 오류 구조를 갖춘 ResponseEntity를 반환합니다. 유효성 검사(MethodArgumentNotValidException)와 제약 조건(ConstraintViolationException)은 별도로 처리합니다. 4xx는 WARN으로, 5xx는 ERROR로 기록합니다.
자주 묻는 질문
“@ControllerAdvice를 사용한 전역 예외 처리” 강의는 무료인가요?
네 — “@ControllerAdvice를 사용한 전역 예외 처리” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Java Academy 강의 전체를 잠금 해제할 수 있습니다. Java Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
“@ControllerAdvice를 사용한 전역 예외 처리”에서 뭘 배우나요?
@ExceptionHandler와 @ControllerAdvice로 모든 컨트롤러의 예외 처리를 중앙화합니다. 브라우저에서 직접 실행하는 실습 코드로 Java Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
Java Academy을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 Java Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 3번째 강의입니다.
“@ControllerAdvice를 사용한 전역 예외 처리” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 Java Academy 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 Java Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.
이 강의의 모든 강의
- 빈 검증: @NotNull, @Size, @Pattern
- 사용자 지정 제약 조건 애너테이션
- @ControllerAdvice를 사용한 전역 예외 처리
- RFC 7807 문제 상세 정보와 일관된 오류 응답