SEB_BE 44일차 - 예외처리

subimm_·2022년 10월 25일
0

코드스테이츠

목록 보기
44/83

💡 오늘의 학습목표

  • Spring MVC 예외처리
  • @ExceptionHandler 를 이용한 예외처리
  • @RestControllerAdice를 이용한 예외처리

📔 @ExceptionHandler를 이용한 예외처리

📖 Controller 레벨에서의 예외 처리

  • Spring이 처리하는 에러 응답 메시지를 직접 처리하도록 코드 수정
  • Spring에서의 예외는 애플리케이션에 문제가 발생할 경우, 문제를 알려서 처리뿐만 아니라 유효성 검증에 실패했을때와 같이 이 실패를 하나의 예외로 간주하여 예외를 던져서 예외 처리 유도

MemberController에 @ExceptionHandler 적용

  • handleException() 메서드 추가
  • 회원 등록 과정에서 Requst Body의 유효성 검증 실패 시 예외 처리 과정
    • 클라이언트에서 회원 등록을 위해 MemberController의 postMember() 핸들러 메서드에 요청
    • RequestBody에 유효하지 않은 데이터로 유효성 검증에 실패하고 MethodArgumentNotValidException이 발생
    • MemberController 에 애너테이션이 추가된 예외 처리 메서드가 있어 handleException()메서드가 예외를 전달 받음
    • (1)과 같이 객체에서 getBindingResult().getFieldErrors()를 통해 발생한 에러 정보 확인
    • (2)에서 에러 정보를 ResponseEntity를 통해 Response Body로 전달


  • 문제가 된 JSON 프로퍼티와 에러메시지만 전달 받기
    • JSON 응답 객체가 배열 ? DTO클래스에서 검증해야하는 멤버 변수에서 유효성 검증에 실패하는 멤버 변수들이 하나 이상이 될 수 있기 때문에 실패 에러 역시 하나 이상이 될 수 있음.
    • 필드의 에러 정보를 담기 위해서 List 객체 이용, 한개의 필드 에러 정보는 FieldError 라는 별도의 클래스를 ErrorResponse 클래스의 멤버 클래스로 정의

      클래스가 멤버 변수와 멤버 메서드를 포함하듯이 static 멤버 클래스를 포함할 수 있다.

✔ ErrorResponse를 사용하도록 MemberController의handleException() 메서드 수정

  • (2)와 같이 필요한 정보들만 선택적으로 ErrorResponse.FieldError 클래스에 담아서 List로 변환 후 List<ErrorResponse.FieldError>를 ResponseEntity 클래스에 실어서 전달

📖 ExceptionHandler의 단점

  1. 각각의 Controller 클래스에서 @ExceptionHandler 애너테이션을 사용하여 처리를 해야되므로 각 Controller 클래스마다 코드 중복이 발생
  2. Controller에서 처리해야되는 예외가
    유효성 검증 실패에 대한 예외(MethodArgumentNotValidException) 만 있는 것이 아니라
    하나의 Controller 클래스 내에서 @ExceptionHandler를 추가한 에러 처리 핸들러 메서드가 늘어남.

📔 @RestControllerAdvice를 이용한 예외처리

📖 @RestControllerAdvice를 사용한 예외처리 공통화

  • 특정 클래스에 @RestControllerAdvice 애너테이션을 추가하면 여러개의 Controller 클래스에서 @ExceptionHandler, @InitBinder, @ModelAttribute가 추가된 메서드를 공유가능
  • 예외 처리를 공통화 할 수 있다.

✔ MemberController 클래스에서 @ExceptionHandler 로직 제거
✔ ExceptionAdvie 클래스 정의

✔ Exception 핸들러 메서드 구현

  • 각 Contorller 예외 처리 공통화가 가능해짐.

✔ ErrorResponse 수정

  • (2) 의 URI 변수로 넘어오는 값의 유효성 검증에 대한 에러(ConstrainViolationException) 처리 구현
    • ErrorResponse 클래스가 Error Response 생성 가능하게 수정

  1. DTO 클래스의 유효성 검증에서 발생하는 MethodArgumentNotValidException 에러 응답
  2. URI 변수 값 검증에서 발생하는 ConstraintViolationException 에러 응답
  • (1)은 MethodArgumentNotValidException 로부터 발생하는 에러 정보를 담는 멤버 변수
    • 즉, DTO 멤버 변수 필드의 유효성 검증 실패로 발생한 에러 정보를 담는 멤버 변수
  • (2)는 ConstraintViolationException 로부터 발생하는 에러 정보를 담는 멤버 변수
    • 즉, URI 변수 값의 유효성 검증에 실패로 발생한 에러 정보를 담는 멤버 변수
  • (3)은 ErrorResponse 클래스의 생성자, 생성자 앞에 private 지정
    • ErrorResponse 클래스는 new 방식으로 객체 생성 불가
      대신에 of() 메서드를 이용하여 객체 생성 가능 (역할을 명확하게 해줌)
  • (4)는 MethodArgumentNotValidException 에 대한 ErrorResponse 객체 생성
    • 에러 정보를 얻기 위해 필요한 것이 BindingResult 객체로 이 of() 메서드를 호출하는 쪽에서 BindingResult 객체를 파라미터로 넘겨주면 된다.
    • BindingResult 객체로 에러 정보 추출 후 가공은 FieldError 클래스에게 위임
  • (5)는 ConstraintViolationException 에 대한 ErrorResponse 객체 생성
    • 에러 정보를 얻기 위해 필요한 것이 Set<ConstraintViolation<?>> 객체로 of() 메서드를 호출하는 쪽에서 Set<ConstraintViolation<?>> 객체를 파라미터로 넘겨주면 된다.
    • 에러 정보를 가공하는 일은 ConstraintViolationError 클래스에게 위임
  • (6) 에서는 필드 (DTO 클래스의 멤버 변수)의 유효성 검증에서 발생하는 에러 정보 생성
  • (7) 에서는 URI 변수 값에 대한 에러 정보 생성

    of() 메서드
    네이밍 컨벤션으로 객체 생성시 어떤 값들의(of~) 객체를 생성한다는 의미에서 사용

✔ Exception 핸들러 메서드 수정

  • ErrorResponse 정보를 만드는 역할을 ErrorResponse 클래스가 대신 해줌.
  • ErrorResponse 객체를 바로 리턴
  • @ResponseStatus 애너테이션으로 HTTP Status 를 HTTP Response에 포함.
    • @RestControllerAdicce = @ControllerAdvice+ @ResponseBody
profile
코린이의 공부 일지

0개의 댓글