Spring-Bean Validation-HTTP 메시지 컨버터

희운·2025년 5월 20일

SpringBoot

목록 보기
6/10
@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(BindException.class)
    public ResponseEntity<ErrorResponse> handleBindException(BindException ex) {
        List<ErrorResponse.FieldError> errors = ex.getBindingResult()
            .getFieldErrors().stream()
            .map(fe -> {
                String field   = fe.getField();
                String code    = fe.getCode();           // typeMismatch, NotBlank, Size, ...
                String message = fe.getDefaultMessage(); // 메시지 소스에서 치환된 최종 메시지

                // (선택) code에 따라 메시지 커스터마이징
                if ("typeMismatch".equals(code)) {
                    message = String.format("'%s' 필드는 올바른 형식이 아닙니다.", field);
                }

                return new ErrorResponse.FieldError(field, code, message);
            })
            .collect(Collectors.toList());

        ErrorResponse body = new ErrorResponse("잘못된 입력이 있습니다.", errors);
        return ResponseEntity
                .badRequest()
                .body(body);
    }

    // (Optional) @RequestBody + @Valid 검증용
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<ErrorResponse> handleJsonValid(MethodArgumentNotValidException ex) {
        // ex.getBindingResult() 활용 방식은 위와 동일
        // 필요하면 여기서 따로 처리
        return handleBindException(new BindException(ex.getBindingResult()));
    }

    // 에러 응답 DTO
    public static class ErrorResponse {
        private String message;
        private List<FieldError> errors;
        // constructors, getters

        public static class FieldError {
            private String field;
            private String code;
            private String reason;
            // constructors, getters
        }
    }
}

다음과 같이

  • @ModelAttribute 에서 Validation에 실패할 경우(Controller에 BindingResult가 없는 경우 BindinException 이 발생한다.

  • @RequestBody에서는 Validation에 실패할 경우
    MethodArgumentNotValidException 이 발생하는것을 알수있다.

위의 두경우는 BindingResult 가 없는 경우에 해당한다.(그래서 에러헨들러가 의미가 있는것)
하지만 Controller 에 BindingResult가 있는경우 중요한점이 @ModelAttribute 에서는 필드 하나하나를 검증하기 때문에
타입오류가 발생해도 Validation에서 type이 맞지않은 에러를(이름이 기억이 안남) BindingResult 에 추가를 하지만

@RequestBody 에서는 타입이 맞지않으면 애초에 객체 자체가 생성이 안되기 때문에 Validation 자체가 적용이 안된다

profile
기록하는 공간

0개의 댓글