Data Binding(데이터 바인딩)은 클라이언트에서 전달된 데이터를 컨트롤러의 매개변수나 객체에 자동으로 변환하여 주입하는 과정이다. 스프링 MVC에서는 @ModelAttribute, @RequestParam, @PathVariable, @RequestBody 등을 활용하여 데이터를 바인딩할 수 있다.
DataBinder가 요청 데이터를 컨트롤러의 매개변수 또는 객체에 매핑.TypeMismatchException).Validator 또는 @Valid / @Validated를 사용하여 데이터 유효성 검사 진행.@PostMapping("/user")
public String createUser(@ModelAttribute UserDto userDto) {
// userDto에 폼 데이터가 자동으로 바인딩됨
return "success";
}
Validation(유효성 검사)은 바인딩된 데이터가 올바른 값인지 확인하는 과정이다. 스프링에서는 javax.validation의 @Valid, org.springframework.validation.annotation.Validated 등을 사용하여 유효성 검사를 수행할 수 있다.
@Valid, @Validated)Validator 구현)BindingResult 활용)스프링에서는 javax.validation.constraints 패키지의 애노테이션을 활용하여 유효성 검사를 할 수 있다.
@Valid를 사용한 유효성 검사import jakarta.validation.constraints.*;
public class UserDto {
@NotBlank(message = "이름은 필수 입력값입니다.")
private String name;
@Email(message = "올바른 이메일 형식이어야 합니다.")
private String email;
@Min(value = 18, message = "나이는 18세 이상이어야 합니다.")
private int age;
}
@PostMapping("/user")
public String createUser(@Valid @ModelAttribute UserDto userDto, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
return "error";
}
return "success";
}
@Valid는 DTO에 선언된 검증 애노테이션을 적용한다.BindingResult를 활용하면 검증 오류가 발생했을 때 적절한 처리를 할 수 있다.@Validated와 그룹별 검증스프링에서 제공하는 @Validated를 사용하면 특정 그룹에 따라 검증 규칙을 다르게 적용할 수 있다.
public interface CreateGroup {}
public interface UpdateGroup {}
public class UserDto {
@NotBlank(groups = CreateGroup.class, message = "이름은 필수 입력값입니다.")
private String name;
@Email(message = "올바른 이메일 형식이어야 합니다.")
private String email;
@Min(value = 18, groups = CreateGroup.class, message = "나이는 18세 이상이어야 합니다.")
private int age;
}
@PostMapping("/user")
public String createUser(@Validated(CreateGroup.class) @RequestBody UserDto userDto, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
return "error";
}
return "success";
}
@Validated(CreateGroup.class)를 사용하여 특정 검증 그룹을 적용할 수 있다.Validator 인터페이스를 활용한 검증Validator 인터페이스를 구현하면 커스텀한 검증 로직을 적용할 수 있다.
Validator 구현import org.springframework.validation.Errors;
import org.springframework.validation.ValidationUtils;
import org.sprintframework.validation.Validator;
public class UserValidator implements Validator {
@Override
public boolean supports(Class<?> clazz) {
return UserDto.class.equals(clazz);
}
@Override
public void validate(Object target, Errors errors) {
UserDto user = (UserDto) target;
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "name", "field.required", "이름은 필수 입력값입니다.");
if (user.getAge() < 18) {
errors.rejectValue("age", "field.min", "나이는 18세 이상이어야합니다.");
}
}
}
@PostMapping("/user")
public String createUser(@ModelAttribute UserDto userDto, BindingResult bindingResult) {
new UserValidator().validate(userDto, bindingResult);
if (bindingResult.hasErrors()) {
return "error";
}
return "success";
}
스프링에서 WebDataBinder를 활용하여 Validator를 글로벌하게 등록할 수도 있다.
@ControllerAdvice
public class GlobalValidatorConfig {
@InitBinder
public void initBinder(WebDataBinder binder) {
binder.addValidators(new UserValidator());
}
}
UserValidator가 자동으로 실행된다.| 기능 | 설명 | 주요 애노테이션/클래스 |
|---|---|---|
| Data Binding | 요청 데이터를 객체에 자동 매핑 | @ModelAttribute, @RequestParam, @RequestBody |
| 기본 Validation | 애노테이션을 활용한 유효성 검사 | @Valid, @Validated, @NotBlank, @Email 등 |
| 그룹별 Validation | 그룹별로 유효성 검사를 적용 | @Validated(groups = GroupName.class) |
| 커스텀 Validator | 직접 Validator를 구현하여 검증 | Validator 인터페이스 |
| 글로벌 Validator | 모든 컨트롤러에서 Validator 자동 적용 | @InitBinder, ControllerAdvice |
이와 같이 스프링에서는 다양한 방식으로 데이터 바인딩과 검증을 수행할 수 있다.