Spring - ExceptionHandler , ControllerAdvice 정리

한승희·2023년 7월 2일
0

Java-몰랐던것들

목록 보기
1/1

Exception 처리가 소스에서 너무 덕지덕지 붙다보니 소스에 집중은 안가고 오히려 오류처리 로직만 보이는
겁나 불편한 상황이 되고 말았다.

나만 이런 상황이 된것은 아니었는지 스프링에서 감사하게도 ExceptionHandler와 ControllerAdvice 라는 어노테이션을 제공해 주고 있다.

간략하게만 정리하기로 한다. (캡쳐는 너무 귀찮아..)


1. ExceptionHandler

만약 한개의 클래스 파일 내에서 특정 오류에 대해 다뤄야 하는경우, 다루어야 하는 @Controller 또는 @RestController에서 별도 메소드를 지정, @ExceptionHandler 어노테이션을 선언하여 처리해준다.

<예시>

@RestController
public class ExceptionHandlingTest{
	@Autowire
    private MyService ms;
    @GetMapping("/hello")
    public void hello(){
    	return "hello";
    }
    @GetMapping("/service")
    public String callSomething(){
    	return ms.serviceMessedMethod(); //예외가 발생하는 서비스 메서드 호출
    }
    @GetMapping("/conexception")
    public void controllerException(){
    	throw new NullPointerException(); // 컨트롤러 자체에서 예외 발생.
    }
    
    //ExceptionHandler 호출
    @ExceptionHandler(NullPointerException.class)
    public Object HandleNPE(Exception e){
    	System.err.println(e.getClass());
        return "An error Occurred!";
    }
}

이 경우, 서비스를 호출하다가 에러가 발생해도, ExceptionHandler가 잘 처리해준다.
컨트롤러에서 에러가 나도 잘 잡아주고.

2. ControllerAdvice

@Controller , @RestController 전역에서 발생한 오류를 처리하고 싶다면 @ControllerAdvice를 이용하자.
@ControllerAdvice를 선언한 클래스에 각각의 익셉션에 대해 @ExceptionHandler를 이용해주면 된다.

@ContorllerAdvice
public class AdviceExample{
	@ExceptionHandler(NullPointerException.class)
    public String handler(){
    	return "you screwed!";
    }
}

만약에 특정 패키지의 @Contorller / @RestController 빈에 대해 처리하고 싶다면

@ControllerAdvice("com.example.xorhd1222.somemodule.controller")

와 같이 처리해주면 된다.
그 외로, @RestControllerAdvice 라는 놈이 있는데, 이 놈은 @ResponseBody가 추가되어 있으므로,
API서버에서 에러 응답으로 객체를 던져줘야 하는 경우에는 이 놈을 적극 사용해주자.
(내가 일하는 곳에서는 쓰지를 않아..ㅠㅠ)

실무에선 어쩔껀데?

라는 의문이 있는데, 나도 안쓰니 뭐 어쩔수 있나.
실무에서 잘 쓰는 친구에게 물어보니

  1. 에러는 포맷이 일정해야 한다.
  2. 근데 저 둘만 쓰다가는 각각의 에러에 대해 적절한 포맷을 제공하지 못한다.
  3. 그러니 @ExceptionHandler와 함께 @ResponseStatus(value=HttpStatus.NOTFOUND))
    같은 것도 같이 넣어서 써주거나
  4. 1차로 enum으로 에러코드를 한곳에 관리하면서 에러객체를 만들어서 리턴 후, 위의 두녀석을 사용해서 에러를 처리해본다고 한다.

이렇게 2차로 거르면, 에러코드는 코드대로 처리하고, 익셉션은 익셉션대로 처리하면서 중복된 코드를 사용하지 않게 된다고 한다.
Enum 객체에 대해서도 좀 더 기억을 되새김질 해봄직하다.


좀 더 상세한 설명에 대해서는 이 갓글 을 참고하는게 좋을것 같다.

0개의 댓글