티스토리 뷰
bean-validation
환경
- MACOS
- JAVA 9
- gradle 4.6
- maven 3.5.3
설치
gradle, maven
$ brew update && brew upgrade && brew cleanup
$ brew install gradle
$ brew install maven
bean-validation 이란?
- 데이터를 검증하기 위한 Java 표준 기술
- 검증규칙은 Annotaion으로 사용
- 데이터의 검증은 Runtime시에 이루어 짐
- 애노테이션을 이용하여 bean 유효성 검사를 위한 Java API 스펙
Intellij에서 프로젝트 생성
새 프로젝트 생성
Gradle -> Java를 선택 후 next
GroupId와 ArtifactId, Version를 원하는 형식으로 작성 후 next
Gradle home에 gradle이 설치된 경로 (gradle/version/libexec까지 선택) 작성 후 next
build.gradle 파일에 자신이 원하는 maven을 작성
compile, testCompile등은 search.maven에서 원하는 maven을 검색 후 gradle에 맞는 형식을 작성후 dependencies 하위 목록에 작성
build.gradle에 작성을 완료후 Import Changes를 선택
그후 projectname/src/main/java/ 하위에 원하는 코드를 작성한다.
예제
이 튜토리얼에서는 간단한 계정 클래스를 만든다.
필드 값으로는 UUID id, String username, String name, String email이 있고 생성자와 getter를 작성 id는 UUID.randomUUID()로 랜덤값이 생성한다.
코드 작성 시 필드 값에 대해 어노테이션으로 조건을 지정할 수 있다.
어노테이션 정보를 간략하게 설명하면 다음과 같다.
- @NotNull - 값이 Null인지 확인하고, 반드시 값이 들어가야한다.
- @NotBlank - null, "", " "를 허용하지 않는다.
- @Size - size를 지정할 수 있다. 속성으로 Min Max 등을 가진다.
- @Email - email형식이 맞는지 확인한다. @Email은 3월12이 현재 버그가 발견돼 밑의 코드처럼 정규표현식과 함께 사용
- @AssertTrue - true 검증
- @NotEmpty - null이나 size가 0 검증 (String, Collection)
- @NotBlank - null이나 whitespace 검증 (String)
- @Positive, @PositiveOrZero - 숫자 검증
- @Negative, @NegativeOrZero - 숫자 검증
- @Past, @PastOrPresent - 날짜 검증
- @Future, @FutureOrPresent - 날짜 검증
JunitTest/src/main/java/io/wisoft/tutorial/domain/Account
package io.wisoft.tutorial.domain;
import javax.validation.constraints.*;
import java.util.UUID;
public class Account {
@NotNull
private UUID id;
@NotBlank(message = "username may not be empty.")
@Size(min = 4,max = 10, message = "username must be between 4 and 10 characters long.")
private String username;
@Size(min=4, max=20, message = "name must be between 4 and 20 characters long.")
@NotBlank(message = "name may not be empty.")
private String name;
@Email(regexp ="^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.(?:[a-zA-Z]{2,6})$", message = "Email must be a well-formed email address")
@NotBlank(message = "비어있지 않다.")
private String email;
public Account(){}
Account(String username, String name, String email) {
this.id = UUID.randomUUID();
this.username = username;
this.name = name;
this.email = email;
}
public UUID getId() {
return id;
}
public String getUsername() {
return username;
}
public String getName() {
return name;
}
public String getEmail() {
return email;
}
}
당연히 테스트 코드는 projectname/src/test/ 하위에 작성된다.
.junitTest/src/test/io/wisoft/tutorial/domain/AccountTest
package io.wisoft.tutorial.domain;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.shadow.com.univocity.parsers.annotations.Nested;
import javax.validation.ConstraintViolation;
import java.util.List;
import java.util.Set;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.*;
@DisplayName("The account validator test case")
class AccountTest {
private Account account;
@org.junit.jupiter.api.Nested
@DisplayName("Account ID test case")
class IdValidation {
@Test
@DisplayName("정상적인 Account ID")
void checkIdValidationSuccess() {
account = new Account("bomin","BoMin Seo", "tjqh55@gmail.com");
assertNotNull(account);
assertThat(account.getId()).isNotNull();
}
}
@org.junit.jupiter.api.Nested
@DisplayName("Account username test case")
class UsernameValidation{
@Test
@DisplayName("정상적인 Username")
void checkUsernameValidationSuccess(){
account = new Account("bomin","BoMin Seo","tjqh55@gmail.com");
final Set<ConstraintViolation<Account>> result =
SimpleBeanValidator.getViolationsOfCheckValidate(account);
assertThat(account.getUsername()).isEqualTo("bomin");
assertThat(result.isEmpty()).isTrue();
}
@Test
@DisplayName("username must be between 4 and 10 characters long.")
void checkUsernameValidationSuccessFail(){
account = new Account("bom","BoMin Seo","tjqh55@gmail.com");
final String result =
SimpleBeanValidator.getMessageOfCheckValidate(account);
assertThat(result).contains("username must be between 4 and 10 characters long.");
}
@Test
@DisplayName("Username is blank, username may not be empty.")
void checkUsernameBlankValidationFail() {
account = new Account("","bomin Seo", "tjqh55@gmail.com");
final List<String> result =
SimpleBeanValidator.getMessageListOfCheckValidate(account);
assertThat(result.contains("username may not be empty.")).isTrue();
assertThat(result.contains("username must be between 4 and 10 characters long.")).isTrue();
}
}
}
위 테스트 코드에서 SimpleBeanValidator는 코드의 중복성을 배제하기 위헤 따로 빼서 작성한 부분이다.
.junitTest/src/test/io/wisoft/tutorial/domain/SimpleBeanValidator
package io.wisoft.tutorial.domain;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
public class SimpleBeanValidator {
private final static ValidatorFactory VALIDATOR_FACTORY = Validation.buildDefaultValidatorFactory();
private final static Validator VALIDATOR = VALIDATOR_FACTORY.getValidator();
public static <T> String getMessageOfCheckValidate(final @NotNull T t){
// 메세지가 1개 일때 사용
final Set<ConstraintViolation<T>> violations = VALIDATOR.validate(t);
String result = null;
for (ConstraintViolation<T> violation : violations) {
result = violation.getMessage();
}
return result;
}
public static <T> List<String> getMessageListOfCheckValidate(final @NotNull T t){
// 메세지가 2개 이상일때 List를 사용 (Blank, Size)
final Set<ConstraintViolation<T>> violations = VALIDATOR.validate(t);
final List<String> result =new ArrayList<>();
for (ConstraintViolation<T> violation : violations) {
result.add(violation.getMessage());
}
return result;
}
public static <T> Set<ConstraintViolation<T>> getViolationsOfCheckValidate(final @NotNull T t){
// 하나의 값일 때 사용
return VALIDATOR.validate(t);
}
}
.Account.class , AccountTest.class 비교
==========Account.class부분==========
~~~~
public class Account {
@NotNull // id필드 값은 Null이 될 수 없다는 조건을 건다.
private UUID id;
~~~~
}
~~~~
========================================
==========AccountTest.class부분==========
class AccountTest {
private Account account;
@org.junit.jupiter.api.Nested
@DisplayName("Account ID test case")
class IdValidation {
@Test
@DisplayName("정상적인 Account ID")
void checkIdValidationSuccess() {
account = new Account("bomin","BoMin Seo", "tjqh55@gmail.com");
assertNotNull(account); //Account.class에서 id 필드는 Null이 될 수 없다는 조건이 맞는지 확인
assertThat(account.getId()).isNotNull(); // id 값이 Null인지 아닌지 확인
}
}
}
~~~
========================================
'ETC' 카테고리의 다른 글
처음 배우는 스프링 부트 2 리뷰 (0) | 2018.11.19 |
---|---|
이더리움 미스트 설치 (0) | 2018.03.12 |
gitlab 설치 (0) | 2018.03.12 |
윈도우 다중 원격접속 (0) | 2018.03.12 |
grafana tutorial (0) | 2018.03.12 |