우당탕탕

[Spring] ControllerAdvice와 ExceptionHandler에 대해 본문

Tech/Spring

[Spring] ControllerAdvice와 ExceptionHandler에 대해

모찌모찝 2022. 9. 27. 19:00
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가 캐치하기 이전에 발생하는 에러가 존재한다. 이는 톰캣 다운그레이드를 통해 해결할 수 있다. 

Comments