우당탕탕
[Spring] ControllerAdvice와 ExceptionHandler에 대해 본문
ControllerAdvice와 ExceptionHandler에 대해
@ExceptionHandler란?
@ExceptionHandler란 Bean에서 발생하는 예외를 잡아 하나의 메서드에서 처리해주는 어노테이션이다.
ExceptionHandler 어노테이션에 설정한 예외가 발생한다면 해당 handler가 작동하며 어노테이션 옆에 value 값을 줘서 캐치할 예외를 설정해 줄 수 있다. ( 여러 예외를 한 곳에 넣을 수도 있다 )
해당 내용은 아래의 코드를 통해 확인해보자
@RestController
public class ExceptionController {
// 한개만 설정할 경우
@ExceptionHandler(NullPointerException.class)
public String allException(Exception e) {
return "exception!!";
}
// 두개를 설정한 경우
@ExceptionHandler({HttpClientErrorException.class, HttpServerErrorException})
public String htttpException(Exception e) {
return "Httpexception!!";
}
}
ExceptionHandler에서 두개이상 설정 시에는 ({ 예외. class }) 를 통해 예외를 여러 개 설정할 수 있다. 위 코드에서는 Http 4xx 에러를 잡는 HttpClientErrorException과 5xx 에러를 잡는 HttpServerErrorException을 사용하여 Http 에러를 캐치하는 예제를 작성한 것이다.
@ExceptionHandler의 경우 Controller와 RestController에서는 사용이 가능하지만 @Service나 @Repository가 적용된 곳에는 사용이 불가능하다.
또한 @ExceptionHandler는 해당 코드를 작성한 Controller 내에서만 적용된다. 다른 컨트롤러에서 발생한 예외는 처리하지 않는다.
그렇다면 핸들러를 모든 컨트롤러에 작성해야하는것일까? 이러한 불편한점은 @ControllerAdvice를 통해 해결할 수 있다.
@ControllerAdvice란?
@ControllerAdivce 어노테이션은 모든 @Controller에 대해 예외를 잡아 처리해주는 어노테이션이다.
클래스 파일위에 @ControllerAdvice 어노테이션을 붙이면 돼서 간편하며 클래스 안에는 @ExceptionHandler를 통해 내가 핸들링하고 싶은 예외를 잡아서 처리하면 된다.
@ControllerAdvice 말고도 @RestControllerAdvice 어노테이션도 존재하는데 이는 Controller와 RestController의 차이와 비슷하게 @ResponseBody 어노테이션이 추가된 형태인 것이다.
@RestControllerAdvice는 @ResponseBody 어노테이션이 추가되었기 때문에 예외를 객체로 리턴할 수 있게 된다.
에러 페이지로 리다이렉트를 시키기를 원한다면 @ControllerAdvice를 사용하여 예외처리를 진행하면 되고, API 서버를 운영하면서 객체만 리턴 시키려면 @RestControllerAdvice를 사용하면 된다.
만약 적절하게 섞어 사용하기 위해서는 @ControllerAdvice를 사용하고 객체를 리턴해야 하는 부분에만 @ResponseBody을 붙여 사용하면 된다.
위에서 ControllerAdvice 어노테이션을 통해 모든 컨트롤러의 에러를 캐치할 수 있다고 하였는데 어노테이션 옆에 패키 지명 작성을 통해 패키지 제한 또한 가능하다.
@ControllerAdvice("패키지명")
추가.
URL에 |나 \를 사용하여 400 에러가 발생하는 경우가 존재하는데 이는 ExceptionHandler가 캐치하기 이전에 발생하는 에러가 존재한다. 이는 톰캣 다운그레이드를 통해 해결할 수 있다.
'Tech > Spring' 카테고리의 다른 글
[Spring] 초보자를 위한 Spring Security: JWT로 웹 앱 보안 강화하기 (0) | 2024.09.14 |
---|---|
[Spring] JPA에서 Persistable 인터페이스로 성능 최적화하기: isNew() 메서드 활용법 (0) | 2024.08.16 |
[Spring] IoC(Inversion of Control)과 DI(Dependency Injection) 이란? (0) | 2022.09.01 |
[Spring] 필터(Filter)와 인터셉터(Interceptor) 차이 (1) | 2022.08.23 |
[Spring] 디스패처 서블릿이란? (Dispatcher Servlet) (3) | 2022.08.22 |