<참고이미지1>
@ExceptionHandeler
> 해당하는 컨트롤러에서 예외 발생 시, 해당하는 클래스의 에러를 잡는 역할을 한다.
그 후 지정해놓은 메소드가 호출되며 처리가 된다. + 지정한 예외 또는 예외의 자식 클래스는 모두 잡을 수 있다.
> 추가 사항
해당 작업만을 진행하고 Postman으로 출력할 시 우측 상단의 Http상태코드값은 200 (정상출력코드) 으로 나올 것이다.
이는 당연한 것이다. 에러를 잡았다한들, 그 처리에 대한 출력을 정상적으로 했기 때문이다.
혹여 전달하는 Http 상태값 또한 오류에 대한 정보로 기재하여 출력하고 싶을 때는
참고이미지1의 2개 사례와 같이
@ResponseStatus(HttpStatus.BAD_REQUEST
혹은
ResponseEntity(~~~, HttpStatus.BAD_REQUEST)를 활용하면 된다.
하지만, 위와 같은 방법들은 개별적으로 에러코드 및 메시지를 지정해줘야한다.
그러니, 재사용성을 강화하기 위해 아래와 같이 enum클래스로 에로코드를 명시해 둔 뒤
@Getter
@AllArgsConstructor
public enum ErrorCode {
UNAUTHORIZED_401(HttpStatus.UNAUTHORIZED, "권한이 없습니다."),
// 날짜 입력 오류
DateTimeException_400(HttpStatus.BAD_REQUEST, "잘못된 날짜입니다."),
/*
* 해당 주석 위로 enum 코드 추가 바랍니다.
* 코드 추가시 간편하게 진행하기 위해 생성한 미사용 코드입니다. 사용하지마세요.
* 생성이유 : enum 마지막 요소에 ; 을 입력해야하기에, 끝부분에 추가하게 될 경우 ; 을 재입력해야함
*/
DO_NOT_USED(null, null);
private final HttpStatus httpStatus;
private final String message;
}
아래와 같은 에러가 발생하면,
RequestException 을 생성하는 코드를 작성한다. (파라미터는 ErrorCode내용으로 준다)
private Folder folderObject(Long id) {
return folderRepository.findById(id).orElseThrow(
() -> new RequestException(ErrorCode.FOLDER_ID_NOT_FOUND_404)
);
}
RequestException 생성자는 아래와 같은 로직으로 작동한다.
해당 클래스는 RuntimeException을 상속받는다.
그 후 ErrorCode를 매개변수로 받아 값을 초기화한다.
@Getter
public class RequestException extends RuntimeException{
private final HttpStatus httpStatus;
public RequestException(ErrorCode errorCode) {
super(errorCode.getMessage());
this.httpStatus = errorCode.getHttpStatus();
}
}
@ControllerAdvice에서 RequestException에 해당하는 (RuntimeException 예외인 것들은)
예외들을 @ExceptionHandler 메소드에 따라 처리한다.
ResponseDto.fails가 발생할 시, RequestException의 Status, Message값을 받아온다.
@RestControllerAdvice
public class RestApiExceptionHandler {
@ExceptionHandler(value = { RequestException.class })
public ResponseEntity<ResponseDto<Object>> handleApiRequestException(RequestException e) {
return new ResponseEntity<>(ResponseDto.fails(e.getHttpStatus(), e.getMessage()),
e.getHttpStatus()
);
}
}
ResponseDto.fails가 발생할 시, 매개변수로 RequestException의 HttpStatus, Message가 주어지며,
위 데이터가 Error 클래스 객체생성에 사용된다.
해당 데이터는 ResponseEntity의 데이터로 추가된다.
public static <T> ResponseDto<T> fails(HttpStatus httpStatus, String message) {
return new ResponseDto<>(false, null, new Error(httpStatus,message));
}
}
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class Error {
private HttpStatus httpStatus;
private String message;
}
@RestControllerAdvice
> 여러 컨트롤러단에서 발생한 예외를 모아서 처리할 수 있는 컨트롤러 구역
@ControllerAdvice는 대상으로 지정한 여러 컨트롤러에 @ExceptionHandler, @InitBinder 기능을 부여해주는 역할을 한다.
특정클래스, 특정 애노테이션이 있는 컨트롤러, 특정 패키지를 직접 지정하여 적용할 수 있다.
지정을 생략하면 모든 컨트롤러에 적용된다.
해당 구역에 @ExceptionHandler를 모두 옮겨서 예외를 처리한다.
최종정리
@ExceptionHandler 와 @ControllerAdvice를 조합하면 예외를 깔끔하게 해결할 수 있다.
'Spring' 카테고리의 다른 글
JOIN종류 / ON절의 의미 / Query 조회기능 최적화 팁 (0) | 2022.11.07 |
---|---|
Elasticsearch란? (작성중) (0) | 2022.11.05 |
WebSocket / STOMP (1) | 2022.10.28 |
querydsl 사용법! (0) | 2022.10.27 |
Spring. Filter/Interceptor (0) | 2022.10.13 |
댓글