클라이언트 측에서 넘어온 데이터를 객체에 바인딩할 때 @Valid와 @Validated로 유효성 검사를 할 수 있습니다.
 
우선 각 빌드에 맞게 의존성을 추가합니다.
 
Gradle일 경우, build.gradle에 의존성 추가
dependencies{
    ...
    implementation 'org.springframework.boot:spring-boot-starter-validation'
}
 
Maven일 경우, pom.xml에 의존성 추가
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
    <version>2.6.3</version>
</dependency>
 
유효성 검사를 위한 어노테이션 적용
객체에 유효성 검사를 적용할 필드에 어노테이션을 적용합니다.
 
public class Article {
    private Long id;
    
    @NotEmpty
    private String title;
    
    @NotEmpty
    private String content;
    
    ...
}
 
어노테이션 종류
| Anotation | 제약조건 | 
| @NotNull | Null 불가 | 
| @Null | Null만 입력 가능 | 
| @NotEmpty | Null, 빈 문자열 불가 | 
| @NotBlank | Null, 빈 문자열, 스페이스만 있는 문자열 불가 | 
| @Size(min= , max= ) | 문자열, 배열등의 크기가 만족하는가? | 
| @Pattern(regex= ) | 정규식을 만족하는가? | 
| @Max(숫자) | 지정 값 이하인가? | 
| @Min(숫자) | 지정 값 이상인가 | 
| @Future | 현재 보다 미래인가? | 
| @Past | 현재 보다 과거인가? | 
| @Positive | 양수만 가능 | 
| @PositiveOrZero | 양수와 0만 가능 | 
| @Negative | 음수만 가능 | 
| @NegativeOrZero | 음수와 0만 가능 | 
| @Email | 이메일 형식만 가능 | 
| @Digits(integer= , fraction = ) | 대상 수가 지정된 정수와 소수 자리 수 보다 작은가? | 
| @DecimalMax(value= ) | 지정된 값(실수) 이하인가? | 
| @DecimalMin(value= ) | 지정된 값(실수) 이상인가? | 
| @AssertFalse | false 인가? | 
| @AssertTrue | true 인가? | 
 
Controller에서 유효성 검사
해당 유효성 검사를 할 것인지에 대해 Controller에서 @Valid를 통해 적용할 수 있습니다.
 
@RestController
public class ArticleController {
    ...
    @PostMapping("/article/write")
    public ResponseEntity articleWrite(@RequestBody @Valid Article article) {
        ...
    }
}
 
@Validated
@Validated 어노테이션은 스프링에서 제공하는 @Valid 기능을 확장한 어노테이션이고 그룹핑 목적으로 사용합니다. 예를 들어 위 예제에서 본 Article 클래스에서 @NotEmpty를 통해 게시글 제목과 내용에 null값과 빈 문자열이 들어가지 못하도록 설정했는데 @Valid를 사용하면 필드에 적용된 모든 어노테이션에 대한 검증이 이뤄지므로 특정 필드만 유효성 검사를 하고 싶을 경우에는 필드를 그룹핑하여 일부만 유효성 검사를 할 수 있습니다.
 
그룹을 지정하기 위한 용도의 클래스를 하나 생성하고 그룹별 interface를 클래스 내에 생성합니다.
 
public class ValidationGroups {
    public interface groupA {};
    public interface groupB {};
}
 
 
그리고 적용할 필드에 그룹을 적용하면 그룹핑이 끝납니다.
 
public class Article {
    private Long id;
    
    @NotEmpty(group = {ValidationGroups.groupA.class})
    private String title;
    
    @NotEmpty(group = {ValidationGroups.groupB.class})
    private String content;
    
    ...
}
 
위에서 본 예제 Controller에 유효성 검사 시 게시글 내용만 null값을 체크하고 싶으면 아래 코드처럼 적용하시면 됩니다.
 
@RestController
public class ArticleController {
    ...
    @PostMapping("/article/write")
    public ResponseEntity articleWrite(@RequestBody 
                                       @Validated(ValidationGroup.groupB.class) Article article) {
        ...
    }
}