Back-End/Spring Boot
예외처리
newny
2023. 8. 25. 01:27
반응형
서블릿 밖으로 까지 예외가 전달되는 경우 서블릿의 예외 처리 방식
@GetMapping("/error-ex")
public void errorEx() {
throw new RuntimeException("예외 발생");
}
@GetMappint("/error-500")
public void error500(HttpServletResponse response) throw IOException {
response.sendError(500);
}
'Exception'의 경우서버 내부에서 처리할 수 없는 오류가 발생한 것으로 생각해서 HTTP 상태 코드 500을 반환한다.
서블릿의 예외처리 2가지 방식
- Exception (예외)
- reponse.sendError (HTTP 상태코드, 오류메세지)
ExceptionResolver 활용
public class MyHandlerExceptionResolver implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
try {
if (ex instanceof IllegalArgumentException) {
log.info("IllegalArgumentException resolver to 400");
response.sendError(HttpServletResponse.SC_BAD_REQUEST, ex.getMessage()); // 500예외를 400예외로 바꿔줌
return new ModelAndView(); //빈값 반환 -> 뷰를 렌더링 하지 않고 정상 흐름으로 서블릿이 리턴됨
}
} catch (IOException e) {
log.error("resolver ex", e);
}
return null;
// null을 반환하면 다음 ExceptionResolver를 찾아서 실행함, 만약 처리할 수 있는 ExceptionResolver가 없다면
// 예외처리가 안되고, 기존에 발생한 예외를 서블릿 밖으로 던짐
}
}
- ExceptionResolver를 등록할 때 configureHandlerExceptioResolver() 를 사용하면 스프링이 기본으로 등록하는 ExceptionResolver가 제거되므로 주의해야함 → 따라서 extendHandlerExceptionResolver() 를 사용해야함
- 서블릿 컨테이너까지 예외가 올라가면 복잡하고 지정분하게 추가 프로세스가 실행된다. 반면에 ExceptionResolver를 사용하면 예외처리가 상당히 깔끔해 진다.
ResponseStatusExceptionResolver
@ResponseStatus
예외에 위의 어노테이션을 적용하면 HTTP 상태 코드를 변경해준다
@ResponseStatus(code = HttpStatus.BAD_REQUEST, reason = "error.bad")
public class BadRequestException extends RuntimeException {}
DefaultHandlerExceptionResolver
스프링 내부 예외 처리
ExceptionHandlerExcetpionResolver
@ExceptionHandler
- 서블릿 컨테이너를 다시 왔다갔다 할 필요 없이, exception 처리를 한 후 정상 로직으로 반환해줌
- 해당 어노테이션을 사용한 메소드를 포함하는 컨트롤러 전체에서 사용됨
- 따라서 @ResponseStatus 어노테이션으로 상태코드를 변경하지 않으면 정상 로직으로 반환되기 때문에 결과가 200으로 뜸
- 메소드 파라미터가 스프링 컨트롤러의 파라미터처럼 다양함 (리턴타입도 마찬가지)
반응형