티스토리 뷰

프로그램을 개발할때 예외처리는 흐름을 정하는데 매우 중요한 부분이다.

예외처리를 하는 경우와 방법은 다양하다.

  • 메소드 내에서 어떤 상황을 예측해서 try - catch
  • 요구사항에 대해 if - else 문으로 처리
  • 스프링 시큐리티에서 인터셉터로 잡아서 UnauthorizedException 같은 예외처리

 

이러한 다양한 예외처리를 적용하다보면 코드는 엄청나게 복잡해지고 유지보수하기 어려워진다.

또한 비즈니스 로직에 집중하기 어렵고, 그와 무관한 코드가 더 많아지는 경우도 생긴다.

이 문제에 대해 스프링에서는 @ExcepionHandler와 @ControllerAdvice 어노테이션으로 개선할 수 있다.

 

 

@ExceptionHandler

- @Controller와 @RestController가 적용된 Bean 내에서 발생하는 예외를 잡아서 하나의 메소드로 처리한다.

 

@ExceptionHandler(NullPointerException.class) 

public Object nullex(Exception e) { System.err.println(e.getClass()); return "myService"; } }

위처럼 어노테이션의 매개변수로 처리하고 싶은 예외 클래스를 등록하여 사용하면된다.

이는 nullex 메소드가 존재하는 Controller에 해당하는 Bean에서 NPE가 발생한다면 "myService"를 리턴할 것이다.

 

- 이런식으로 여려개의 예외 클래스 등록도 가능하다.

@ExceptionHandler({ Exception1.class, Exception2.class})

특징

  • @Controller 혹은 @RestController가 적용된 Bean에서만 사용할 수있다.
  • @ExceptionHandler를 등록한 메소드가 Controller의 다른 메소드의 리턴타입과 무관한 타입을 리턴하여도 상관없다.
  • @ExceptionHandler를 등록한 Controller에만 적용된다.
  • 예를 들어, A Controller에 NPE를 잡는 @ExceptionHandler를 등록하여도, B Controller에서 발생하는 NPE를 처리할 수 없다.
  • 위 예시에선 메소드의 파라미터로 예외 클래스를 받아왔는데 이또한 자유롭게 받아도 된다.

 

 

@ControllerAdvice

- 앞서 설명한, @ExceptionHandler가 하나의 클래스에 대한 것이라면,

@ControllerAdivce는 모든 Controller에서 발생하는 예외에 대해 전역으로 작용하다.

 

@RestControllerAdvice public class MyAdvice { 

    @ExceptionHandler(CustomException.class) public String custom() { 

        return "hello custom";

    }

}

 

위처럼 새로운 클래스파일을 생성해서 @ControllerAdive 어노테이션을 등록하기만하면 된다.

그 후, @ExceptionHandler 로 처리하고 싶은 예외를 잡아 처리하면 된다.

 

@ControllerAdivce는 @ControllerAdivce와 @RestControllerAdivce 2가지가 존재하는데,

RestControllerAdive Annotation을 까보면

 

@Target(ElementType.TYPE) 

@Retention(RetentionPolicy.RUNTIME) 

@Documented

@ControllerAdvice 

@ResponseBody 

public @interface RestControllerAdvice {

    //... 

}

 

이처럼 @ControllerAdvice와 @ResponseBody가 내장되어있다.

 

따라서 구현하는 서버에 따라,

1. viewResolver를 통해 예외 발생시 에외 처리 페이지로 리다이렉트 시켜야 한다면

@ContollerAdive + @ExceptionHandler 조합

 

2. API서버여서 에러 응답 객체를 리턴해야한다면

@RestContollerAdive + @ExceptionHandler 조합 혹은

@ContollerAdive + @ExceptionHandler + @ResponseBody 조합을 사용하면 된다.

 

쉽게 말해 웹 서버든 API서버이든 @ContollerAdive + @ExceptionHandler 조합으로 예외를 잡을 수 있고, @ResponseBody를 필요에 따라 적용하면 된다.

 

또한, 모든 Controller에 대해 예외를 잡긴하되 패키지 단위로 제한할 수도있다.

@RestControllerAdvice("com.example.demo.login.controller")

 



출처

https://jeong-pro.tistory.com/195

 

@ControllerAdvice, @ExceptionHandler를 이용한 예외처리 분리, 통합하기(Spring에서 예외 관리하는 방법, 실

예외 처리 과정 프로그래밍에서 예외 처리는 아주 중요하면서도 아주 어렵다. 과하다할 만큼 상세하고 다양하게 예외를 잡아 처리해준다면, 클라이언트도 그렇고 서버도 그렇고 더 안정적인 프

jeong-pro.tistory.com

Comments