Spring MVC에서의 예외 처리

 

 

Spring MVC는 애플리케이션에서 발생할 수 예외를 효율적으로 처리하도록 몇 가지 방법을 제공한다.

 

 

 

➤ @ExceptionHandler를 이용한 Controller 레벨에서의 예외 처리

 

유효성 검증에서 실패했을 때 클라이언트가 전달 받는 Response Body는 애플리케이션에서 예외(Exception)가 발생했을 때, 내부적으로 Spring에서 전송해주는 에러 응답 메시지 중 하나이다.

 

Spring에서 예외는 유효성 검증이 실패했을 때 등 문제가 발생하면 실패를 하나의 예외로 간주하여 이 예외를 던져서 (throw) 예외 처리를 유도한다.

 

 

▶️ @Slf4J

Simple Logging Facade for Java

Logging

  • 개발 중이나 완료 후 발생할 수 있는 오류에 대해 디버깅하거나 운영중인 프로그램 상태를 모니터링 하기 위해 필요한 정보(로그)를 기록하는것

 

Logback과 같은 백엔드 Logging Framework의 facade pattern

 

https://www.slf4j.org/

 

SLF4J

Simple Logging Facade for Java (SLF4J) The Simple Logging Facade for Java (SLF4J) serves as a simple facade or abstraction for various logging frameworks (e.g. java.util.logging, logback, log4j) allowing the end user to plug in the desired logging framewor

www.slf4j.org

 

 

▶️ @ExceptionHandler

예외 처리 메서드로 선언

 

 

▶️ .getBindingResult().getFieldErrors()

에러 정보를 확인할 수 있다

 

 

➤ ErrorResponse 클래스 만들기

 

DTO 클래스 유효성 검증 실패 시

실패한 필드에 대한 Error 정보만 담아서 응답으로 전송하기 위한 클래스

 

Response Body의 JSON 응답 객체가 배열이다.

✅ 배열인 이유?

DTO 클래스에서 유효성 검증에 실패하는 멤버변수가 하나 이상이 될 수 있기 때문에 유효성 검증 실패 에러 역시 하나 이상이 될 수 있다.

-> 유효성 검증에 실패한 필드의 에러 정보를 담기 위해서 List 객체를 이용

FieldError라는 별도의 static class를 ErrorResponse 클래스의 안에 정의한다.

FieldError클래스는 ErrorResponse 클래스의 내부(Inner) 클래스라고 부르기 보다는

ErrorResponse 클래스의 static 멤버 클래스라고 부르는 것이 적절하다.

필요한 정보들만 골라서 Response body에 담을 수 있다.

 

 

 

➤ @ExceptionHandler 의 단점

 

1. 코드 중복이 발생한다.

각각의 Controller 클래스에서 @ExceptionHandler 애너테이션을 사용해서 유효성 검증 실패에 대한 에러 처리를 해야한다.

 

2. 예외 마다 에러 처리 핸들러 메서드가 늘어난다.

Controller 클래스 내에서 발생할 수 있는 예외(Exception)은 한가지만 있는게 아니다.

그러면 각각의 예외 마다 @ExceptionHandler를 추가한 에러 처리 핸들러 메서드가 늘어나게 된다.

 

 

https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-ann-exceptionhandler

 

Web on Servlet Stack

Spring Web MVC is the original web framework built on the Servlet API and has been included in the Spring Framework from the very beginning. The formal name, “Spring Web MVC,” comes from the name of its source module (spring-webmvc), but it is more com

docs.spring.io

 

 

 

 

❑ @RestControllerAdvice 를 이용한 예외 처리

 

➤ 예외 처리 공통화

 

특정 클래스에 @RestControllerAdvice 애너테이션을 추가하면 여러개의 Controller 클래스에서 @ExceptionHandler, @InitBinder, @ModelAttribute가 추가된 메서드를 공유해서 사용할 수 있다.

 

 

@RestControllerAdvice 애너테이션을 추가한 클래스

➡️ 예외 처리를 모든 Controller에 공통화 할 수 있게 된다.

 

 

▶️ @InitBinder, @ModelAttribute 애너테이션

 

JSP, Thymeleaf 같은 서버 사이드 렌더링(SSR, Server Side Rendering) 방식에서 주로 사용된다.

 

 

 

Controller 클래스에서 @ExceptionHandler 로직 제거

-> ExceptionAdvice 클래스 정의 (@RestControllerAdvice)

-> 모든 Controller의 에러를 동시에 처리할 수 있게 된다.(AOP, 공통 관심사)

 

에러를 정보를 전달하는 객체(Error Response)와 에러 정보를 추출하고 가공하는 static 멤버 클래스로 역할을 분리한다.

 

기능이 늘어남에 따라 Error Response 클래스의 구현 복잡도가 늘어나지만

에러 유형에 따른 에러 정보 생성 역할을 분리함으로써 사용자 입장에서 한층 더 편리해진다.

 

 

▶️ of() 메서드

  • 네이밍 컨벤션(Naming Convention)
  • 객체 생성시 어떤 값들의(of~) 객체를 생성한다는 의미
  • 객체.of(원하는 값)

 

ExceptionAdvice 클래스에서 ErrorResponse 클래스에 of를 사용해서 에러 객체 전달한다.

ResponseEntity 대신 ErrorResponse 객체 그대로 반환하고

@ResponseStatus 애너테이션을 이용해서 attribute로 HTTP Status 전달한다.

 

 

※ @RestControllerAdvice vs @ControllerAdvice

 

SpringMVC 4.3버전 이후부터 @RestControllerAdvice 지원

@RestControllerAdvice = @ControllerAdvice + @ResponseBody

JSON 형식의 데이터를 Response Body로 전송하기 위해서 ResponseEntity로 데이터를 래핑할 필요가 없다.

 

 

 

 

읽어주셔서 감사합니다. 좋은하루 되세요 🤩