
@Valid 기반 Spring Validation과 폼 검증 완벽 가이드
Spring Validation은 사용자의 입력값을 서버 단에서 검증할 수 있는 강력한 기능입니다. @Valid, @Validated, BindingResult를 활용하면 복잡한 입력 검증 로직을 깔끔하게 처리할 수 있습니다. 이 글에서는 Spring MVC 환경에서의 폼 검증 전체 흐름과 실무 적용 방법을 정리합니다.
1. Spring Validation이란?
Spring에서는 Java Bean Validation(JSR-380)을 기반으로, @NotNull, @Size, @Email 같은 어노테이션으로 폼 입력값을 손쉽게 검증할 수 있습니다. 검증 대상 객체 앞에 @Valid 또는 @Validated를 선언하면 자동으로 동작합니다.
2. 폼 객체 예제
public class UserForm {
@NotBlank(message = "이름은 필수입니다.")
private String name;
@Email(message = "이메일 형식이 아닙니다.")
private String email;
@Min(value = 18, message = "18세 이상만 가입할 수 있습니다.")
private int age;
// Getter / Setter 생략
}
3. 컨트롤러에서의 @Valid와 BindingResult 사용
@Valid 또는 @Validated는 BindingResult와 함께 사용할 때만 검증 오류를 컨트롤러에서 직접 처리할 수 있습니다.
@PostMapping("/register")
public String register(@Valid UserForm form, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
return "registerForm"; // 오류 발생 시 다시 폼으로 이동
}
userService.save(form);
return "redirect:/success";
}
4. 글로벌 에러 vs 필드 에러
- 글로벌 에러: 객체 전체에 대한 오류 (
bindingResult.reject()) - 필드 에러: 특정 필드에 대한 오류 (
bindingResult.rejectValue())
5. 사용자 정의 검증 추가
복잡한 로직은 커스텀 Validator로 분리합니다.
@Component
public class UserFormValidator implements Validator {
@Override
public boolean supports(Class<?> clazz) {
return UserForm.class.isAssignableFrom(clazz);
}
@Override
public void validate(Object target, Errors errors) {
UserForm form = (UserForm) target;
if (form.getName().equals("admin")) {
errors.rejectValue("name", "not.allowed", "admin은 사용할 수 없는 이름입니다.");
}
}
}
6. @InitBinder로 Validator 등록
@InitBinder
public void init(WebDataBinder binder) {
binder.addValidators(new UserFormValidator());
}
7. HTML에서 에러 출력
<form th:action="@{/register}" method="post" th:object="${userForm}">
<input type="text" th:field="*{name}" />
<p th:if="${#fields.hasErrors('name')}" th:errors="*{name}"></p>
</form>
8. 실무 팁
@Validated는 그룹 지정 가능,@Valid는 단순 검증에 사용- REST API에서는
@RequestBody와 함께@Valid적용 - 입력값 필터링은 클라이언트와 서버 양쪽에서 처리해야 안전함
9. 결론
Spring Validation은 사용자의 잘못된 입력을 서버에서 안전하게 걸러내는 중요한 역할을 합니다. @Valid, BindingResult, 사용자 정의 Validator를 적절히 조합하면 실무에서도 강력하고 견고한 입력 검증 로직을 구축할 수 있습니다.