WEB개발

[Spring] ExceptionResolver

wooyeon06 2023. 1. 2. 13:40

스프링에는 HandlerExceptionResolverComposite 이라는 파일에 다음 순서로 ExceptionResolver 들이 등록되어있다.

 

  1. ExceptionHandlerExceptionResolver: 이 예외 해결자는 사용자가 정의한 @ExceptionHandler 메서드를 찾아서 예외를 처리합니다. 따라서 가장 먼저 호출되어 예외가 발생한 경우에 대해 사용자가 정의한 처리 로직을 수행합니다.

  2. ResponseStatusExceptionResolver: 이 예외 해결자는 @ResponseStatus 애노테이션이 적용된 예외를 처리합니다. 예외에 해당 애노테이션이 적용되어 있으면 설정된 HTTP 상태 코드와 함께 해당 응답을 반환합니다. 따라서 두 번째로 호출됩니다.

  3. DefaultHandlerExceptionResolver: 이 예외 해결자는 기본적인 예외 처리 로직을 수행합니다. 컨트롤러에서 발생한 예외를 처리하고 기본적인 오류 페이지로 리디렉션합니다. 따라서 마지막으로 호출됩니다.

 

커스텀 ExceptionResolver가 있을 시 맨처음 수행됩니다.

 

 

 

HandlerExceptionResolver의 기본 흐름과 목적(Exception Resolver)

(인터셉터가 적용되어 있는것 주의)

https://maenco.tistory.com/entry/Spring-MVC-API-Error-API-%EC%98%A4%EB%A5%98-%EC%B2%98%EB%A6%AC

 

 

1. preHandle을 호출한다

2. 핸들러(컨트롤러)를 호출한다

3. 예외가 발생한다

4. postHandle은 호출되지 않고 afterCompletion이 되어진다

 

https://maenco.tistory.com/entry/Spring-MVC-API-Error-API-%EC%98%A4%EB%A5%98-%EC%B2%98%EB%A6%AC

 

 

1. preHandle을 호출한다

2. 핸들러(컨트롤러)를 호출한다

3. 예외가 발생한다

4. postHandle을 여전히 호출되지 않고 ExceptionResolver에 예외를 처리할 수 있는지 확인한다

5. afterCompletion을 호출한다

6. 만약 ExceptionResolver에서 처리할 수 있다면 ModelAndView를 반환한다

 

 

 


 

ExceptionResolver의 종류

 

ExceptionResolver를 찾지 못하면 다음 Resolver를 검색하는데 이 과정에서 우선순위가 존재하며 아래와 같다

 

1. ExceptionHandlerExceptionResolver 

 

: Spring MVC에서 예외를 처리하는 방법을 결정하는 데 사용되는 예외 해결자입니다. 이 해결자는 컨트롤러에서 발생한 예외를 처리하고 적절한 응답을 생성합니다.

 

일반적으로 @ExceptionHandler 애노테이션과 함께 사용되며, 이 애노테이션을 메서드에 적용하여 특정 예외를 처리하는 메서드를 지정할 수 있습니다.

 

@ControllerAdvice // 전역 예외 처리를 위한 어노테이션
public class DemoExceptionHandler {

    @ExceptionHandler(Exception.class) // 예외 타입을 지정하여 처리할 메소드를 정의합니다.
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) // 응답 상태 코드를 설정합니다.
    @ResponseBody // 응답 본문을 설정합니다.
    public String handleException(Exception e) {

        return "예외가 발생했습니다: " + e.getMessage();

    }
}

 

 

RETURN TYPE

• @ReponseBody

• HttpEntity<B>, ResponseEntity<B>

• String

• View

• Map, Model

• @ModelAttribute

 

 

 

@ExceptionHandler 또한 예외처리에서 우선순위 (부모예외처리 후 자식예외처리 )

@ExceptionHandler(부모예외.class) 
public String 부모예외처리()(부모예외 e) {}

@ExceptionHandler(자식예외.class) 
public String 자식예외처리()(자식예외 e) {}

 

 

여러 Exception처리

@ExceptionHandler({AException.class, BException.class})
public String ex(Exception e) {
    log.info("exception e", e);
}

 

 

2. ReponseStatusExceptionResolver

 

: Spring MVC에서 HTTP 응답 상태 코드를 설정하는데 사용되는 예외 해결자입니다. 이 해결자는 @ResponseStatus 애노테이션이 적용된 예외를 처리하고, 해당 애노테이션에서 지정한 HTTP 응답 상태 코드와 함께 클라이언트에게 응답을 반환합니다.

 

@ResponseStatus(code = HttpStatus.BAD_REQUEST, reason = "잘못된 요청 오류") 
public class BadRequestException extends RuntimeException {
}

 

ResponseStatusExceptionResolver가 작동하는 코드를 확인해보면 결국 서블릿의

response.sendError(statusCode, resolvedReson)을 사용하기 때문에 sendError(400)을 호출하게 되면 WAS에서 오류 페이지를 요청하게 됩니다.

 

@GetMapping("/api/responsereoslver")
public String responseStatus() {
    throw new BadRequestException();
}

 

이를 위와 같이 API 오류에 반환하게 된다면 아래와 같이 출력됩니다.

 

{
    "status": 400,     
    "error": "Bad Request",
    "exception": "hello.exception.exception.BadRequestException", 
    "message": "잘못된 요청 오류",\
    "path": "/api/responsereoslver"
}

 

 

 

 

3. DefaultHandlerExceptionResolver

 

DefaultHandlerExceptionResolver는 Spring MVC에서 기본적인 예외 처리를 수행하는 예외 해결자입니다. 이 예외 해결자는 컨트롤러에서 발생한 예외를 처리하고 기본적인 오류 페이지로 리디렉션합니다.

일반적으로 컨트롤러에서 발생한 예외를 처리하기 위해 @ExceptionHandler 애노테이션을 사용하는 것이 일반적입니다. 그러나 @ExceptionHandler로 처리되지 않은 예외는 DefaultHandlerExceptionResolver가 처리합니다.

 

이때 DefaultHandlerExceptionResolver가 각 상황에 맞는 응답 코드를 리턴해줍니다.

 

요청에 맞는 컨트롤러(핸들러)를 못 찾는 경우 -> 404 Not Found

컨트롤러 실행 중 예외가 발생하는 경우 -> 500 Internal Server Error

컨트롤러의 파라미터 타입 미스매치 경우 -> 400 BadRequest

 

 

 


 

정리

 

 

4.1. 예외가 발생하였기 때문에 ExceptionResolver가 작동한다, 이때 가장 우선순위가 높은 @ExceptionHandler에서 가 작동하고 해당 컨트롤러에 발생한 예외를 처리할 수 있는 @ExceptionHanlder가 존재하는지 확인한다

4.2. ResponseStatus에 지정된 응답 코드를 반환한다

5. afterCompletion 호출

6. 예외처리가 되었으므로 API 응답

 

 

 

 

 

 

 

 

 


 

 

https://whitepro.tistory.com/392

https://maenco.tistory.com/entry/Spring-MVC-API-Error-API-%EC%98%A4%EB%A5%98-%EC%B2%98%EB%A6%AC