ResponseEntityExceptionHandler 사용법

컴공생의 코딩 일기·2024년 9월 24일
0

스프링

목록 보기
17/17

ResponseEntityExceptionHandler 란

ResponseEntityExceptionHandler는 Spring MVC에서 제공하는 예외처리 클래스로, Spring MVC 애플리케이션에서 발생하는 표준적인 예외들을 효율적으로 처리할 수 있도록 도와준다.

ResponseEntityExceptionHandler는 아래 사진과 같이 Spring MVC에서 발생하는 예외를 미리 @ExceptionHandler로 정의해 놓았다. ResponseEntityExceptionHandler로 상속만 받으면 이러한 예외를 직접 구현할 필요가 없어진다.

 @ExceptionHandler({
HttpRequestMethodNotSupportedException.class, 
HttpMediaTypeNotSupportedException.class, 
HttpMediaTypeNotAcceptableException.class, 
MissingPathVariableException.class, 
MissingServletRequestParameterException.class, 
MissingServletRequestPartException.class, 
ServletRequestBindingException.class, 
MethodArgumentNotValidException.class, 
HandlerMethodValidationException.class, 
NoHandlerFoundException.class, 
NoResourceFoundException.class, 
AsyncRequestTimeoutException.class, 
ErrorResponseException.class, 
MaxUploadSizeExceededException.class, 
ConversionNotSupportedException.class, 
TypeMismatchException.class, 
HttpMessageNotReadableException.class, 
HttpMessageNotWritableException.class, 
MethodValidationException.class, BindException.class
})

하지만 ResponseEntityExceptionHandler는 body 값을 null로 처리하는 단점이 있다.

@Nullable
    protected ResponseEntity<Object> handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException ex, HttpHeaders headers, HttpStatusCode status, WebRequest request) {
        pageNotFoundLogger.warn(ex.getMessage());
        return this.handleExceptionInternal(ex, (Object)null, headers, status, request);
    }

    @Nullable
    protected ResponseEntity<Object> handleHttpMediaTypeNotSupported(HttpMediaTypeNotSupportedException ex, HttpHeaders headers, HttpStatusCode status, WebRequest request) {
        return this.handleExceptionInternal(ex, (Object)null, headers, status, request);
    }

그렇기 때문에 handleExceptionInternal를 재정의 해서 body에 값을 넣어 주어야 한다.

    // Validation 에러 재정의 
    @Override
    protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex, HttpHeaders headers, HttpStatusCode status, WebRequest request) {
        return handleExceptionInternal(ex, ValidationResponse.of(status.value(), ex.getBindingResult()),headers,status, request);
    }

    @ExceptionHandler
    public ResponseEntity<Object> customException(CustomException customException, WebRequest webRequest){
        return handleExceptionInternal(customException, customException.getErrorCode(), webRequest);
    }

    @ExceptionHandler
    public ResponseEntity<Object> exception(Exception ex, WebRequest webRequest){
        return handleExceptionInternal(ex, BaseErrorCode.INTERNAL_SERVER_ERROR, webRequest);

    }

    private ResponseEntity<Object> handleExceptionInternal(Exception  ex, ErrorCode errorCode, WebRequest webRequest) {
        return handleExceptionInternal(ex, errorCode, HttpHeaders.EMPTY,errorCode.getHttpStatus(), webRequest);
    }

    // Validation Exception 처리를 위한 handleExceptionInternal 재정의
    protected ResponseEntity<Object> handleExceptionInternal(Exception  ex, ValidationResponse validationResponse,HttpHeaders headers, HttpStatusCode status, WebRequest webRequest) {
        return super.handleExceptionInternal(ex, validationResponse, headers, status, webRequest);
    }

    // handleExceptionInternal 메서드 재정의
    protected ResponseEntity<Object> handleExceptionInternal(Exception ex, ErrorCode errorCode, HttpHeaders headers, HttpStatusCode statusCode, WebRequest request) {
        return super.handleExceptionInternal(
                ex,
                // 커스텀 Response를 만들어 body에 값을 넣는다.
                ApiExceptionResponse.of(errorCode),
                headers,
                statusCode,
                request);
    }
profile
더 좋은 개발자가 되기위한 과정

0개의 댓글