Valid?

Validation?

사용자의 입력값을 검증하기 위해서는 많은 방법이 존재합니다. 프론트앤드에서 자바스크립트로 값을 직접 검증하거나 백앤드에서 MatcherPattern을 통해서 검증을 하기도 하죠. 저는 스프링에서 사용할 수 있는 검증 방법 중 하나를 소개하고자 합니다.

@Valid 어노테이션을 사용하면, 정말 너무 쉬워서 이게 진짜 되나 싶을 정도로 쉽게 입력값을 검증할 수 있습니다.

적용방법

  1. Valid 어노테이션을 사용하기 위해서 pom.xml에 의존성을 추가해줍니다.
1
2
3
4
5
6
7
8
9
10
11
12
<properties>
  <hibernate.validator-version>5.2.4.Final</hibernate.validator-version>
</properties>

...

<!-- Validator -->
<dependency>
  <groupId>org.hibernate</groupId>
  <artifactId>hibernate-validator</artifactId>
  <version>${hibernate.validator-version}</version>
</dependency>
  1. 이제 적용할 클래스에 적용 룰(?)을 지정해줍니다. User는 너무 많이 썻으니.. Vote로..!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class Vote {
    @NotNull private int voteId;
    @NotNull private String title;
    @NotNull private String author;
    @NotNull private String description;
    @NotNull private int categoryId;
    @NotNull private int selectionLimit;
    @NotNull private String imagePath;
    @DateTimeFormat(pattern = "yyyy-MM-dd") private Date submitDatetime;
    @DateTimeFormat(pattern = "yyyy-MM-dd") private Date startDatetime;
    @DateTimeFormat(pattern = "yyyy-MM-dd") @Future private Date endDatetime;
    private boolean deleted;
    private int readCount;
    private List<Candidate> candidates;
}
  1. 컨트롤러 메소드에서 인자 앞에 @Valid를 붙입니다.
1
2
3
4
5
@AdminRequired
@RequestMapping(value = "/{voteId}/form", method = RequestMethod.GET)
public String addVote(@Valid Vote vote) {
    ...
}
  1. 끝입니다. 거짓말 아닙니다. 진지합니다.

검증할 조건은 아래와 같이 많이 있고, 해당 멤버 변수에 맞는 조건을 달아서 사용하시면 됩니다!

1
2
3
4
5
6
7
8
9
10
11
12
13
@AssertFalse : false 값만 통과 가능
@AssertTrue : true 값만 통과 가능
@DecimalMax(value=) : 지정된  이하의 실수만 통과 가능
@DecimalMin(value=) : 지정된  이상의 실수만 통과 가능
@Digits(integer=,fraction=) : 대상 수가 지정된 정수와 소수 자리수보다 적을 경우 통과 가능
@Future : 대상 날짜가 현재보다 미래일 경우만 통과 가능
@Past : 대상 날짜가 현재보다 과거일 경우만 통과 가능
@Max(value) : 지정된 값보다 아래일 경우만 통과 가능
@Min(value) : 지정된 값보다 이상일 경우만 통과 가능
@NotNull : null 값이 아닐 경우만 통과 가능
@Null : null일 겨우만 통과 가능
@Pattern(regex=, flag=) : 해당 정규식을 만족할 경우만 통과 가능
@Size(min=, max=) : 문자열 또는 배열이 지정된  사이일 경우 통과 가능

그리고! 이렇게 검증한 결과를 사용하여 무언가 로직을 따로 처리하고싶은 경우에는..BindingResult 클래스를 인자로 같이 받도록 하면, @Valid 어노테이션을 이용하여 검증한 결과가 매핑됩니다.

1
2
3
4
5
6
7
8
@AdminRequired
@RequestMapping(value = "/{voteId}/form", method = RequestMethod.GET)
public String addVote(@Valid Vote vote, BindingResult bindingResult) {
    if(bindingResult.hasErrors()) {
        throw new UserInvalidException(ExceptionCode.INVALID_USER);
    }
    ...
}