일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- 추천
- Greedy
- 알고리즘
- BOJ
- BFS
- 완전탐색
- benefits
- 영어
- array
- health
- 나는솔로
- 백준
- coding
- 영화
- 코딩 테스트
- 카카오
- 해설
- 넷플릭스
- Movie
- kakao
- 수능
- Recursive
- Algorithm
- 2020
- review
- Netflix
- parametric search
- silver
- 리뷰
- usaco
- Today
- Total
Young
hibernate validator 본문
유효성 검사는 매우 중요한데, 이를 위해 hibernate validator 를 사용하면 기본적인 유효성 검사를 편하고, 깔끔하게 할 수 있다.
이 hibernate validator 를 만들게 된 이유를 보면, 아래와 같이 객체를 전달할 때마다 유효성 검증을 할텐데, 이 때 코드 중복이 너무 많다는 단점을 보완하기 위해서 이것을 만든 것이다.
그래서 아래와 같이 dto 에 각 멤버변수에 대한 제약조건을 모두 명시해 놓으면, 각 층으로 객체를 넘길때마다 유효성 검증하는
코드를 쉽게 작성할 수 있게끔 한다는 목적을 가지고 만들었다.
(docs.jboss.org/hibernate/stable/validator/reference/en-US/html_single/#validator-gettingstarted)
1. 빠르게 적용해보기
1) 의존성 추가
compile group: 'org.hibernate', name: 'hibernate-validator', version: '6.1.0.Final'
2) 어노테이션으로 제약 조건 추가 및 유효성 검사 시행
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
public class Member {
private int memberNum;
@Size(min = 2, max = 10)
@NotBlank
private String name;
@NotBlank
private String tel;
@Range(min = 0, max = 120)
private int age;
@NotBlank
@Size(min = 3, max = 20)
private String id;
@Null
private Date regDt;
@NotBlank // @Size(min = 1) 설정을 한다고 해서, activation 변수가 null 이 아님을 보장할 수 없음!, 주의.
@Size(min = 1, max = 1)
private String activation;
@NotBlank
@Size(min = 5, max = 45)
private String address;
@NotBlank
private Date birth;
@NotBlank
@Size(min = 1, max = 1)
private String sex;
}
|
cs |
@Valid 어노테이션으로 Member dto 유효성 검사를 시도함
1
2
3
4
|
@PostMapping("/insert")
public void insert(@Valid @RequestBody Member member) {
userService.insert(member);
}
|
cs |
2. 어노테이션 종류
애노테이션 |
주요 속성 |
설명 |
지원 타입 |
@AssertTrue @AssertFalse |
|
값이 true인지 또는 false인지 검사한다. null은 유효하다고 판단한다. |
boolean Boolean |
@DecimalMax @DecimalMin |
String value - 최댓값 또는 최솟값
boolean inclusive - 지정값 포함 여부 - 기본 값 true |
지정한 값보다 작거나 같은지 또는 크거나 같은지 검사한다. inclusive가 false면 value로 지정한 값은 포함하지 않는다. null은 유효하다고 판단한다. |
BigDecimal BigInteger CharSequence byte, short, int, long 및 각 래퍼 타입 |
@Max @Min |
long value |
지정한 값보다 작거나 같은지 또는 크거나 같은지 검사한다. null은 유효하다고 판단한다. |
BigDecimal |
@Digits |
int integer - 허용 가능한 정수 자릿수
int fraction - 허용 가능한 소수점 이하 자릿수 |
자릿수가 지정한 크기를 넘지 않는지 검사한다. null은 유효하다고 판단한다. |
BigDecimal BigInteger CharSequence byte, short, int, long 및 관련 래퍼 타입 |
@Size |
int min - 최소 크기 - 기본 값 0
int max - 최대 크기 - 기본 값 |
길이나 크기가 지정한 값 범위에 있는지 검사한다. null은 유효하다고 판단한다. |
CharSequence Collection Map 배열 |
@Null @NotNull |
값이 null인지 또는 null이 아닌지 검사한다. |
||
@Pattern |
String regexp - 정규표현식 |
값이 정규표현식에 일치하는지 검사한다. null은 유효하다고 판단한다. |
CharSequence |
@NotEmpty (2) |
문자열나 배열의 경우 null이 아니고 길이가 0이 아닌지 검사한다. 콜렉션의 경우 null이 아니고 크기가 0이 아닌지 검사한다. |
CharSequence Collection Map 배열 |
|
@NotBlank (2) |
|
null이 아니고 최소한 한 개 이상의 공백아닌 문자를 포함하는지 검사한다. |
CharSequence |
@Positive (2) @PositiveOrZero (2) |
양수인지 검사한다. OrZero가 붙은 것은 0 또는 양수인지 검사한다. null은 유효하다고 판단한다. |
BigDecimal BigInteger byte, short, int, long 및 관련 래퍼 타입 |
|
@Negative (2) @NegativeOrZero (2) |
음수인지 검사한다. null은 유효하다고 판단한다. |
BigDecimal |
|
@Email (2) |
|
이메일 주소가 유효한지 검사한다. null은 유효하다고 판단한다. |
CharSequence |
@Future (2) @FutureOrPresent (2) |
해당 시간이 미래 시간인지 검사한다. OrPresent가 붙은 것은 현재 또는 미래 시간인지 검사한다. null은 유효하다고 판단한다. |
시간 관련 타입 |
|
@Past (2) @PastOrPresent (2) |
해당 시간이 과거 시간인지 검사한다. OrPresent가 붙은 것은 현재 또는 과거 시간인지 검사한다. |
시간 관련 타입 |
* 애노테이션이 속한 패키지: javax.validation.constraints
* 시간 관련 타입: Date, Calendar, Instant, LocalDate, LocalDateTime, MonthDay, OffsetDateTime, OffsetTime, Year, YearMonth, ZonedDateTime 등
3. Validator 객체
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
public class CarTest {
private static Validator validator;
@BeforeClass
public static void setUpValidator() {
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
validator = factory.getValidator();
}
@Test
public void manufacturerIsNull() {
Car car = new Car( null, "DD-AB-123", 4 );
Set<ConstraintViolation<Car>> constraintViolations =
validator.validate( car );
assertEquals( 1, constraintViolations.size() );
assertEquals( "must not be null", constraintViolations.iterator().next().getMessage() );
}
}
|
cs |
Validator 객체를 사용하여, Car 클래스에 기술한 제약 조건을 검사할 수 있다.
보통 많은 코드를 보면, 컨트롤러를 통해서 맵핑될 때만 @Valid 어노테이션을 사용해서 유효성 검사를 하는데, 이 때만 사용하기 위해서 만든 라이브러리가 아니다.
객체가 함수 파라미터로 넘어가면서 내부 값이 변경되는데 이 때도 이 Validator 객체를 가져와 간편하게 유효성 검사를 할 수 있다.
4. bean 제약 종류
-
field constraints
-
property constraints
-
container element constraints
-
class constraints
(docs.jboss.org/hibernate/stable/validator/reference/en-US/html_single/#chapter-bean-constraints)
1) field-level constraints
필드 레벨 제약을 사용하면, getter 메소드가 있어도, 멤버변수 값에 직접 접근하여 값 유효성 검사를 진행한다.
private, public 을 가리지 않고, 검사한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
package org.hibernate.validator.referenceguide.chapter02.fieldlevel;
public class Car {
@NotNull
private String manufacturer;
@AssertTrue
private boolean isRegistered;
public Car(String manufacturer, boolean isRegistered) {
this.manufacturer = manufacturer;
this.isRegistered = isRegistered;
}
//getters and setters...
}
|
cs |
2) property-level constraints
프로퍼티 레벨 제약을 사용하면, getter 메소드를 통해서 값 유효성 검사를 진행한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
package org.hibernate.validator.referenceguide.chapter02.propertylevel;
public class Car {
private String manufacturer;
private boolean isRegistered;
public Car(String manufacturer, boolean isRegistered) {
this.manufacturer = manufacturer;
this.isRegistered = isRegistered;
}
@NotNull
public String getManufacturer() {
return manufacturer;
}
public void setManufacturer(String manufacturer) {
this.manufacturer = manufacturer;
}
@AssertTrue
public boolean isRegistered() {
return isRegistered;
}
public void setRegistered(boolean isRegistered) {
this.isRegistered = isRegistered;
}
}
|
cs |
3) container element constraints
parameterized type 의 type argument 에 직접 적용시킬 수 있는데, 이를 container element constraints 라고 한다.
아래와 같은 곳에 적용시킬 수 있다.
-
java.util.Iterable 구현체 (List, Set)
-
java.util.Map 의 key, value 모두 지원가능
-
java.util.Optional, java.util.OptionalInt, java.util.OptionalDouble, java.util.OptionalLong
1
2
3
4
5
6
|
Set<@ValidPart String> parts = new HashSet<>();
List<@ValidPart String> parts = new ArrayList<>();
Map<@NotNull FuelConsumption, @MaxAllowedFuelConsumption Integer> fuelConsumption = new HashMap<>();
Optional<@MinTowingCapacity(1000) Integer> towingCapacity = Optional.empty();
GearBox<@MinTorque(100) Gear> gearBox; // Custom container type 에도 적용가능
|
cs |
4) class-level constraints
클래스 레벨에서 아래와 같이 연관된 멤버변수들 끼리 제약을 설정할 수도 있다.
클래스 내 멤버변수들 사이에 관계가 있는 경우 사용하기에 좋다.
1
2
3
4
5
6
7
8
9
|
@ValidPassengerCount
public class Car {
private int seatCount;
private List<Person> passengers;
//...
}
|
cs |
5. constraints inheritance
super 클래스 또는 인터페이스에 적용된 제약관련 어노테이션은 이를 상속받거나 구현한 클래스로 모두 상속된다.
6. Object graphs
custom 클래스 A 내의 멤버변수 중에 또다른 custom 클래스 B 의 인스턴스를 담는 변수가 있고, 이 인스턴스의 멤버변수에도 제약 어노테이션이 적용되어 있다고 하자.
클래스 A 를 유효성 검사를 하면서, 멤버변수 중 클래스 B 의 인스턴스 내의 멤버변수까지 한 번에 검사가 가능하다.
아래와 같이 @Valid 어노테이션을 추가해주면 된다.
recursive 하게 @Valid 어노테이션을 달고 있는 객체 내에 제약 어노테이션이 있는지 검사하고, 있다면 제약조건 위배를 검사하는 작업을 반복한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
public class Car {
@NotNull
@Valid
private Person driver;
//...
}
public class Person {
@NotNull
private String name;
//...
}
|
cs |
'Web > Spring Framework' 카테고리의 다른 글
spring async (0) | 2020.11.02 |
---|---|
스프링의 기초 (0) | 2020.10.24 |
스프링 프레임워크 주요 디자인 패턴 (0) | 2020.10.24 |