티스토리 뷰
프로그램을 개발할때 예외처리는 흐름을 정하는데 매우 중요한 부분이다.
예외처리를 하는 경우와 방법은 다양하다.
- 메소드 내에서 어떤 상황을 예측해서 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")
출처
'Web' 카테고리의 다른 글
Jackson으로 파싱한 JSON 속성값을 생성자로 전달하기 (0) | 2021.10.12 |
---|---|
JPQL getResultList()과 getSingleResult() (0) | 2021.10.12 |
Jackson과 Gson (Java에서 json 사용하기) (0) | 2021.09.09 |
JPA에서 데이터 접근 (0) | 2021.09.09 |
JPA, ORM, Hibernate, JPQL (0) | 2021.09.09 |