✔ 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
애너테이션을 사용하여 처리를 해야되므로 각 Controller 클래스마다 코드 중복이 발생MethodArgumentNotValidException
) 만 있는 것이 아니라@ExceptionHandler
를 추가한 에러 처리 핸들러 메서드가 늘어남.@RestControllerAdvice
애너테이션을 추가하면 여러개의 Controller 클래스에서 @ExceptionHandler, @InitBinder, @ModelAttribute가 추가된 메서드를 공유가능✔ MemberController 클래스에서 @ExceptionHandler 로직 제거
✔ ExceptionAdvie 클래스 정의
✔ Exception 핸들러 메서드 구현
- 각 Contorller 예외 처리 공통화가 가능해짐.
✔ ErrorResponse 수정
- (2) 의 URI 변수로 넘어오는 값의 유효성 검증에 대한 에러(ConstrainViolationException) 처리 구현
- ErrorResponse 클래스가 Error Response 생성 가능하게 수정
- DTO 클래스의 유효성 검증에서 발생하는
MethodArgumentNotValidException
에러 응답- 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