[Spring] Bean Validation (2)

이연우·2025년 7월 26일

TIL

목록 보기
51/100

💬 에러 메시지 (Field Error)

  • Spring의 Bean Validation은 Default로 제공하는 Message들이 존재하고 임의로 수정할 수 있음

📌 기본 메시지 출력 원리

  • Bean Validation을 적용하면 에러 발생 시 기본 메시지가 자동으로 출력
  • BindingResult에 담긴 오류를 확인하면 Annotation 이름 기반의 메시지가 나옴
@NotNull
@Range(min = 1, max = 9999)
private Integer integerField;
@PostMapping("/error-message")
public String beanValidation(
    @Validated @ModelAttribute TestDto dto,
    BindingResult bindingResult
) {
    if (bindingResult.hasErrors()) {
        return String.valueOf(bindingResult.getFieldError());
    }
    return "회원가입 성공";
}

🧪 테스트 결과 메시지 예시:

default message [널이어서는 안됩니다]

MessageCodesResolver에러 코드 순서대로 메시지를 조회함
기본 구현체DefaultMessageCodesResolver


**🛠️ 에러 메시지 커스터마이징 방법**

1. 어노테이션 message 속성 사용

@NotBlank(message = "이 필드는 공백일 수 없습니다")
private String name;

가장 쉬운 방법
→ 다국어 처리에는 적합하지 않음

2. MessageSource를 활용한 국제화 메시지 처리

  • 메시지 코드 우선순위 (자동 생성됨):
    a. NotNull.objectName.fieldName
    b. NotNull.fieldName
    c. NotNull.FieldType
    d. NotNull (기본 메시지)

💡 MessageSource다국어 메시지 관리를 위한 Spring의 인터페이스


🧱 Object Error (객체 수준 검증)란?

  • 하나의 필드가 아닌 여러 필드의 조합, 관계를 기반으로 하는 검증 로직
  • 예: passwordconfirmPassword가 같은지, price * count >= 10000인지 등

1. @ScriptAssert 사용

@ScriptAssert(
  lang = "javascript",
  script = "_this.password === _this.confirmPassword",
  message = "Passwords do not match"
)

❌ 실무에서는 거의 사용하지 않음

  • 복잡한 로직이나 외부 조회에 대응 불가
  • 유지 보수 어려움

2. Java 코드로 Object Error 구현

💡 요구 사항

  • 총 구매 가격이 10,000원 이상
    price * count ≥ 10000
@PostMapping("/object-error")
public String objectError(
    @Validated @ModelAttribute OrderRequestDto dto,
    BindingResult bindingResult
) {
    int result = dto.getPrice() * dto.getCount();

    if (result < 10000) {
        bindingResult.reject(
            "totalMin",                    // 에러 코드
            new Object[]{10000, result},   // 메시지 인자
            "총 합이 10000 이상이어야 합니다."  // 기본 메시지
        );
    }

    if (bindingResult.hasErrors()) {
        return bindingResult.getAllErrors().get(0).getDefaultMessage();
    }

    return "성공";
}

reject() 메서드는 ObjectError 생성


🔧 기타 팁

📚 @ModelAttribute 바인딩 주의사항

@AllArgsConstructor
public class OrderRequestDto {
    ...
}
  • 기본 생성자가 없고, 매개변수가 있는 생성자만 있을 경우
    → 해당 생성자로 값 바인딩

  • 기본 생성자가 있는 경우 → setter로 바인딩

📌 DTO 설계 시 반드시 기본 생성자를 고려할 것

0개의 댓글