서버 개발을 하다 보면 오류 처리를 해야 될 경우가 매우 많이 존재한다.
오류를 제대로 처리하지 않는다면, 서버가 안정적이지 못하게 동작할 수 있다.
보통의 경우에는 Exception 처리를 try-catch를 통해 해결한다.
하지만 이러한 로직들은 비즈니스 로직이 존재하는 곳에 코드가 써져
코드를 복잡하게 하고 유지보수를 어렵게 만든다.
이런 문제를 개선하기 위해 @ExceptionHandler와 @ControllerAdvice를 사용해 보자.
@ExceptionHandler
@Controller, @RestController가 적용된 bean 내에서 발생하는 예외를 처리할 수 있게 해주는 어노테이션
@RestController
public class HelloController {
@GetMapping("/error")
public void test() {
throw new IllegalArgumentException("test error");
}
@ExceptionHandler(Exception.class)
public ResponseEntity<?> handle(Exception ex) {
return new ResponseEntity<>(new ResponseError(LocalDateTime.now(), "error"), HttpStatus.INTERNAL_SERVER_ERROR);
}
}
@ExceptionHandler는 등록된 해당 Controller에만 적용이 된다.
다른 Controller에서 발생하는 예외는 잡을 수 없다.
여러 Controller에서 동일하게 발생하는 예외는 Controller에 적용된 @ExcptionHandler가 아닌 다른 방법으로 처리해야 한다.
@ControllerAdvice
@Controller, @RestController에서 발생한 예외를 한 곳에서 처리할 수 있는 어노테이션
스프링에서 예외처리를 전역적으로 핸들링하기 위해 사용
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(IllegalArgumentException.class)
public ResponseEntity<?> handleIllegalArguException(IllegalArgumentException e) {
return new ResponseEntity<>(new ResponseError(LocalDateTime.now(), "error"),
HttpStatus.INTERNAL_SERVER_ERROR);
}
}
Controller에 해당하는 모든 예외를 처리할 수 있지만, 사용자가 원한다면 특정 패키지로 제한을 할 수 있다
@ControllerAdvice("com.exam.controller")
@RestControllerAdvice
추가적으로 @RestControllerAdvice에 대해서 간단하게 알아보자
해당 어노테이션은 @ControllerAdvice + @ResponseBody 조합 어노테이션이라 생각하면 된다.
( @Controller, @RestController 관계와 비슷하게 @ResponseBody 설정이 추가된 어노테이션)
( https://joomn11.tistory.com/53?category=936835 )
다만 위에 예시처럼 Exception을 처리한 메서드의 리턴 값을 ResponseEntity로 지정을 한다면 @RestControllerAdvice 어노테이션을 사용하지 않고도 ResponseBody에 결괏값을 실을 수 있다.
@RestControllerAdvice 사용 예시
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(IllegalArgumentException.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public ResponseError handleIllegalArguException(IllegalArgumentException e) {
return new ResponseError(LocalDateTime.now(), "error"));
}
}
@Getter
@Setter
@AllArgsConstructor
public class ResponseError {
private LocalDateTime timestamp;
private String details;
}
다만, @RestControoerAdvice 어노테이션을 사용하는 경우 각각의 Handler 메서드에 @ResponseStatus 어노테이션을 추가해 주어야 한다.
( 해당 정보를 세팅하지 않는다면 디폴트로 200으로 응답)
'Spring > spring-cloud' 카테고리의 다른 글
[Spring] ActiveMQ - Spring 사용해보기 (0) | 2022.04.10 |
---|---|
[Spring] Spring Cloud Config-Asymmetric Key Encryption(비대칭키 암호화) (0) | 2022.01.05 |
[Spring] Spring Cloud Config-Symmetric Key Encryption(대칭키 암호화) (0) | 2022.01.03 |
[Spring] Spring Cloud Config 사용해보기 (Client) (0) | 2021.08.02 |
[Spring] Spring Cloud Config 사용해보기 (0) | 2021.07.30 |