Spring에서 제공하는 annotation으로, Controller에서 발생하는 Exception을 처리하기 위한 Global Exception Handler를 구현할 때 사용됩니다. @ControllerAdvice와 @ResponseBody를 합쳐놓은 어노테이션이다.
추가적으로 @ResponseBody를 통해 객체를 리턴할 수도 있다.
따라서 단순히 예외만 처리하고 싶다면 @ControllerAdvice를 적용하면 되고, 응답으로 객체를 리턴해야 한다면 @RestControllerAdvice를 적용하면 된다.
모든 종류의 Controller에서 발생하는 Exception을 처리하는데 반해, @RestControllerAdvice는 RESTful API를 구현할 때 발생하는 Exception을 처리하는 데 특화되어 있습니다.
이 어노테이션을 메서드에 선언하고 특정 예외 클래스를 지정해주면 해당 예외가 발생했을 때 메서드에 정의한 로직으로 처리할 수 있다.
@RestControllerAdvice
@RequiredArgsConstructor
public class ApiAdvice {
private final MessageSource messageSource;
@ExceptionHandler(Exception.class)
public ErrorResponse exception(Exception ex) {
return new ErrorResponse(new ErrorData("에러가 발생했습니다."));
}
@ExceptionHandler(CodeLapException.class)
public ErrorResponse exception(CodeLapException ex) {
final String message = messageSource.getMessage(ex.getMessage(), null, Locale.getDefault());
return new ErrorResponse(new ErrorData(message));
}
CodeLapException.class
public class CodeLapException extends RuntimeException {
public CodeLapException(ErrorCode errorCode) {
super(errorCode.getMessage());
}
public CodeLapException(ErrorCode errorCode, Throwable cause) {
super(errorCode.getMessage(), cause);
}
}
ErrorCode.class
public enum ErrorCode {
ACTOR_VALIDATE("error.actor.validate"),
INVALID_MEMBER_SIZE("error.member.size.validate"),
NOT_EXISTED_MEMBER("error.member.not.existed"),
ALREADY_EXISTED_MEMBER("error.member.already.existed"),
ANOTHER_EXISTED_MEMBER("error.member.another.existed"),
NOT_ALLOWED_AS_LEADER("error.member.not.allowed.as.leader");
private final String message;
}
message.properties
error.actor.validate=유효한 사용자가 아닙니다.
error.member.size.validate=최대회원수가 최소값 보다 작습니다.
error.member.not.existed=존재하지 않는 회원입니다.
error.member.already.existed=이미 존재하는 회원입니다.
error.member.not.allowed.as.leader=리더는 불가능합니다.
error.member.another.existed=리더 외에 다른 멤버가 있습니다.