게시판 프로젝트를 진행하면서 게시글을 조회하거나 수정하는 경우 PostResponseDto로 엔티티를 변환하여 클라이언트에게 반환하였다.
하지만 조회나 수정 과정에서 요청받은id에 해당하는 게시글이 없거나 수정하하려는 유저와 게시글의 작성자가 다를때는 예외를 발생시켜 중단하도록 로직을 구성하였다.
이때 예외가 발생하면 서버에서는 콘솔창에 예외메시지와 함께 알아볼 수 있지만 클라이언트에게는 아무것도 반환되지 않으므로 어떤 이유로 반환값이 없는지 알 방법이 없다. 그러므로 예외처리를 통해 클라이언트에게 예외가 발생한 이유를 알려주어야한다. 하지만 예외처리를 해당 컨트롤러의 메소드에서 try - catch로 처리하게 되면 성공시에는 ResponseDto로 반환하지만 예외가 터졌을 시에는 반환 타입이 달라져야하는데 한 메소드 안에서 반환타입이 다를 수 없으므로 난관에 봉착하였다.
@ExceptionHandler
@ExceptionHandler어노테이션은 @Controller, @RestController가 적용된 Bean내에서 발생하는 예외를 잡아서 하나의 메서드에서 처리해주는 기능을 한다.
@RestController
public class MyRestController {
...
...
@ExceptionHandler(NullPointerException.class)
public Object nullex(Exception e) {
System.err.println(e.getClass());
return "myService";
}
}
@ExceptionHandler과 함께 처리하고싶은 예외클래스를 등록해주고 메소드안에 예외를 처리하는 로직을 작성하면 된다.
참고로 발생한 예외가 등록된 예외 클래스의 자식클래스라면 그 예외또한 처리된다.
메소드의 리턴값은 어떤 타입도 가능하다. 때문에 글 초반에 설명했던 반환타입이 달라지는 문제를 해결할 수 있다.
이로써 예외처리를 효율적으로 해결할 수 있지만 @ExceptionHandler는 해당 컨트롤러 내에서 발생하는 예외만 처리할 수 있으므로 컨트롤러가 많아지면 같은예외에 대한 처리이지만 다른 컨트롤러에 같은 @ExceptionHandler메소드를 중복되게 작성해야한다. 그렇다면 코드의 양도 늘어날 뿐더러 여러 컨트롤러에 있는 @ExceptionHandler를 유지, 보수하기도 힘들어질것이다.
@ControllerAdvice
@ControllerAdvice는 전역으로 예외를 처리하여 이러한 단점을 해결해준다.
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(RuntimeException.class)
public ResponseEntity<?> applicationHandler(CustomException e){
return ResponseEntity.status(e.getErrorCode().getStatus())
.body(JsonResponse.error(e.getErrorCode().getMessage(), e.getErrorCode().getStatus()));
}
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<?> applicationHandler(MethodArgumentNotValidException e){
return ResponseEntity.status(HttpStatus.BAD_REQUEST)
.body(JsonResponse.error("fail", "잘못된 데이터 형식입니다."));
}
}
클래스에 @ControllerAdvice어노테이션이 붙어있으면 해당 클래스 내에서 @ExceptionHandler매소드를 정의하여 예외를 처리하는 로직을 담을 수 있다.
@ControllerAdvice를 사용함으로써 많은 컨트롤러에서 사용되는 중복 @ExceptionHandler메소드를 방지할 수 있고 하나의 메소드로 모든 컨트롤러에서 작동하기 때문에 유지 보수또한 향상시킬 수 있다.
@ControllerAdvice는 AOP를 이용한 예외처리 방식으로 application 전역에서 발생하는 모든 서비스의 예외를 한곳에서 관리할 수 있게 해준다.
@RestControllerAdvice는 마치 @RestController와 @Controller의 차이와 같이 @ControllerAdvice에서 Json형식으로 반환할 수 있는 어노테이션이다.
'백엔드(Back End) > Spring' 카테고리의 다른 글
[TIL]20230712 - 페이징 처리 (0) | 2023.07.12 |
---|---|
[TIL]20230711 - 회원탈퇴 기능 구현 (0) | 2023.07.11 |
[TIL]20230710 - 게시글 및 댓글에 좋아요 기능 구현 (1) | 2023.07.10 |
[TIL]20230708 - 스프링 컴포넌트 스캔 (0) | 2023.07.09 |
[TIL]20230706 - 스프링 예외 처리 @ExeptionHandler, @ControllerAdvice (0) | 2023.07.06 |