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 |
|---|---|---|
| 2005 | 2025. 11. 30. | Spring Security 6 JWT 인증 구현 |
| 2004 | 2025. 11. 30. | Spring Boot 3.x 새로운 기능 정리 |
| 1824 | 2022. 05. 24. | [ spring ] interceptor 등 스프링에서 @Autowired 인식을 못할때 |
| 421 | 2016. 08. 02. | [ spring-security ] 스프링 시큐리티 csrf (크로스도메인) 설정방법 |
| 349 | 2016. 02. 16. | [ spring ] spring4 jsonp callback |
| 346 | 2016. 02. 08. | [ spring 4 ] 스프링 4 websocket 및 stomp (채팅 및 쪽지 구현) |
| 344 | 2016. 02. 06. | [ spring-security ] 스프링 시큐리티 4 버전에서 hasRole 및 hasAnyRole 안될경우 |
| 328 | 2015. 11. 05. | [ spring security ] 스프링 시큐리티 유저정보 얻는 방법 |
| 311 | 2015. 06. 30. | [ spring ] IOException while loading persisted sessions: java.io.EOFException 해결 |
| 310 | 2015. 06. 29. | [ spring ] How To Get HTTP Request Header In spring ( 스프링에서 http header 값 가져오기) |