사이드 프로젝트에서 예외처리를 위해 조금 더 잘 알기 위해 @RestControllerAdvice를 다시한번 정리 할려고한다.
개발할때마다 초기 설정하는건 금방 까먹는다..

사진에서 보았듯이 @ControllerAdvice + @ResponseBody랑 합쳐져 있는걸 볼 수 있다.
아 @Target은 어노테이션이 어디에 사용할수있는지 Type이니까 클래스 enum에 사용할 수 있거구나 !
@Retenion 은 Annotation 이 실제로 적용되고 유지되는 범위를 의미한다. 그러면 실행 중일때 적용되는구나!
제가 생각에는 ! 코드 유지보수 시점에서 오류 터지는 부분과 데이터 및 결과가 정상 적으로 불러 올경우를 분리해서 코드가 더러워지는 걸 방지 한다고 생각합니다. 이러면 단일 책임에 원칙도 지켜지고 반복적인 작업 try,catch 코드 최소화 할 수 있다고 생각한다.
저는 이 영상 웃기게 봤어요 ㅎㅎ
요약하면
@NoArgsConstructor
@AllArgsConstructor
public class ApiResponse<T> {
private int status; // 상태 코드
private String message;
private T data;
public static <T> ApiResponse<T> success(T data) {
return new ApiResponse<>(200,"success",data);
}
public static <T> ApiResponse<T> error(int status, String message) {
return new ApiResponse<>(status,message,null);
}
}
우리가 공통적인 데이터를 하나의 묶음으로 만들고 success와 error 이렇게 분리하면 error 즉 Excetpion 터졌을때 success 성공했을때 분리해서 관리 할 수 있다 .
@RestControllerAdvice
public class ExceptionController {
//일반적인 예외 처리
@ExceptionHandler(Exception.class)
public ResponseEntity<ApiResponse<Object>> serverError(Exception e){
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(ApiResponse.error(500, e.getMessage()));
}
// url 요청 requestParam이 빠졋을 경우
@ExceptionHandler(MissingServletRequestParameterException.class)
public ResponseEntity<ApiResponse<Object>> handleMissingParam(MissingServletRequestParameterException e) {
return ResponseEntity.badRequest()
.body(ApiResponse.error(400,"요청 메시지가 빠졌습니다"));
}
}
맞는 상태 메세지, 메시지 등으로 처를 할 수 있다.
@GetMapping("/MissingServletRequestParameterException")
public ResponseEntity<ApiResponse<Object>> illegalArgumentException(@RequestParam Integer count) {
return new ResponseEntity<>(HttpStatus.OK);
}

이러면 그전에 try-catch 로 있었던 부분 줄일 수 있다.
가능하다! 이제 서버가 실행 중일 때 에러를 잡고 내가 에러 종류를 다 알 수 도 없고 에러도 커스텀해서 전송 할 수 있다.
@Getter
public enum ExceptionEnum {
ERROR_ENCODE(5001,"암호화가 에러났습니다"),
ERROR_DECODE(5002,"복화중에 에러가 났습니다"),
ERROR_LENGTH(5003,"너무 길어요");
private final int status;
private final String message;
ExceptionEnum(int status, String message) {
this.status = status;
this.message = message;
}
}
enum을 사용해서 우리가 정의할 수 있다. enum을 대표적인 사용방법은
(월,화,수,목,금,토,일) 과 이제 (봄,여름,가을,겨울) 이미 정의해 놓은 것을 말한다. 우리도 에러를 정의해보자!
public class CustomException extends RuntimeException {
private final ExceptionEnum exceptionEnum;
public CustomException(ExceptionEnum exceptionEnum) {
super(exceptionEnum.getMessage());
this.exceptionEnum = exceptionEnum;
}
public int getStatus(){
return exceptionEnum.getStatus();
}
public String getMessage(){
return exceptionEnum.getMessage();
}
}
@RestControllerAdvice 부분에 추가
//커스터 Exception 암호화 부분이나 다른 에러 처리 못할때 정확한 내용을 정리하기위해
@ExceptionHandler(CustomException.class)
public ResponseEntity<ApiResponse<Object>> customException(CustomException e){
return ResponseEntity.status(HttpStatus.BAD_REQUEST)
.body(ApiResponse.error(e.getStatus(), e.getMessage()));
}

오류가 잘 나오는 것을 알 수 있습니다.
security에서도 @RestControllerAdvice를 작성했는데 초반 설정이 더 필요해서 다음 글에는 추가 적으로 작성하겠습니다.
긴 글 읽어주셔서 감사합니다. :)