Contents
see List작성일 2025. 11. 30.
Spring Validation이란?
Spring Validation은 Java Bean Validation(JSR-380)을 기반으로 입력값 검증을 어노테이션으로 선언적으로 처리하는 프레임워크입니다. 컨트롤러에서 DTO 유효성 검사를 간단하게 수행할 수 있습니다.
언제 사용하나요?
- 회원가입, 로그인 폼에서 필수값/이메일/비밀번호 형식 검증
- API 요청 파라미터 유효성 검사
- 비즈니스 로직 수행 전 데이터 무결성 확보
의존성 추가
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>주요 어노테이션
public class UserDto {
@NotBlank(message = "이름은 필수입니다")
private String name;
@Email(message = "이메일 형식이 아닙니다")
private String email;
@Size(min = 8, max = 20, message = "비밀번호는 8-20자")
private String password;
@Min(value = 1, message = "나이는 1 이상")
@Max(value = 150, message = "나이는 150 이하")
private int age;
@Pattern(regexp = "^01[016789]-\\d{3,4}-\\d{4}$",
message = "휴대폰 번호 형식이 아닙니다")
private String phone;
}컨트롤러에서 검증
@PostMapping("/users")
public ResponseEntity<?> createUser(
@Valid @RequestBody UserDto dto,
BindingResult result) {
if (result.hasErrors()) {
List<String> errors = result.getFieldErrors()
.stream()
.map(e -> e.getField() + ": " + e.getDefaultMessage())
.collect(Collectors.toList());
return ResponseEntity.badRequest().body(errors);
}
return ResponseEntity.ok(userService.create(dto));
}커스텀 Validator 만들기
// 커스텀 어노테이션
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = PhoneValidator.class)
public @interface Phone {
String message() default "유효하지 않은 전화번호";
Class<?>[] groups() default {};
Class<?>[] payload() default {};
}
// Validator 구현
public class PhoneValidator
implements ConstraintValidator<Phone, String> {
@Override
public boolean isValid(String value,
ConstraintValidatorContext ctx) {
if (value == null) return true;
return value.matches("^01[016789]-\\d{3,4}-\\d{4}$");
}
}그룹별 검증
// 그룹 인터페이스
public interface OnCreate {}
public interface OnUpdate {}
// DTO에서 그룹 지정
public class UserDto {
@Null(groups = OnCreate.class)
@NotNull(groups = OnUpdate.class)
private Long id;
@NotBlank(groups = {OnCreate.class, OnUpdate.class})
private String name;
}
// 컨트롤러에서 그룹 적용
@PostMapping
public void create(@Validated(OnCreate.class) @RequestBody UserDto dto) {}
@PutMapping
public void update(@Validated(OnUpdate.class) @RequestBody UserDto dto) {}글로벌 예외 처리
@RestControllerAdvice
public class ValidationExceptionHandler {
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<Map<String, String>> handleValidation(
MethodArgumentNotValidException ex) {
Map<String, String> errors = new HashMap<>();
ex.getBindingResult().getFieldErrors().forEach(e ->
errors.put(e.getField(), e.getDefaultMessage())
);
return ResponseEntity.badRequest().body(errors);
}
}자주 쓰는 어노테이션 정리
| 어노테이션 | 설명 |
|---|---|
| @NotNull | null 불가 |
| @NotEmpty | null, "" 불가 |
| @NotBlank | null, "", " " 불가 |
| @Size | 문자열/컬렉션 크기 |
| 이메일 형식 | |
| @Past/@Future | 과거/미래 날짜 |
| @Positive | 양수만 |
spring
| No | 작성일 | Title |
|---|---|---|
| 164 | 2015. 02. 24. | [ spring ] properties 동적으로 사용하기 (context:property-placeholder 및 util:properties) |
| 149 | 2015. 02. 16. | [ Spring Security ] 스프링 시큐리티 미세 접근 제한 |
| 148 | 2015. 02. 13. | [ Spring ] @Valid 어노테이션에 쉽게 매핑하기 |
| 145 | 2015. 01. 26. | [ Spring ] Transaction Isolation [ 트랜젝션 격리 ] 관리 |
| 109 | 2014. 12. 23. | [ spring ] transaction propagation [ 트랜젝션 전파 ] 관리 |
| 103 | 2014. 10. 29. | [ spring ] 스프링에서 스케줄링(Schedule) 등록하는 방법 |
| 44 | 2014. 09. 29. | [ spring security ] 스프링 시큐리티 xml 설정 |
| 43 | 2014. 09. 29. | [ spring security ] 스프링 시큐어리티 access 옵션 |
| 40 | 2014. 09. 29. | [ mybatis ] 마이바티스 map 이나 bean 을 이용하지 않고 2개이상 파라메터 전달하기 |
| 39 | 2014. 09. 26. | [ spring ] view(jsp) 에서 htmlEscape 사용하기 |