Contents

[Mastering Spring 5.0] 6.3 Bean Validation

Mastering Spring 5.0 μŠ€ν„°λ””

μŠ€ν”„λ§ 5.0 λ§ˆμŠ€ν„° μŠ€ν„°λ””
μŠ€ν”„λ§ 5.0 λ§ˆμŠ€ν„° μŠ€ν„°λ”” ν•™μŠ΅ λ‚΄μš© μ •λ¦¬μž…λ‹ˆλ‹€.

Bean Validation

데이터 μœ νš¨μ„± 검증 (Validation) 은 λͺ¨λ“ κ³„μΈ΅μ—μ„œ κ³΅ν†΅μ μœΌλ‘œ λ°œμƒν•˜λŠ” μž‘μ—…μ΄λ‹€. λ§Œμ•½ λͺ¨λ“  κ³„μΈ΅μ—μ„œ λ™μΌν•œ λ‚΄μš©μ˜ Validation 둜직이 각각의 λ ˆμ΄μ–΄λ³„λ‘œ κ΅¬ν˜„λ˜μ–΄ μžˆλ‹€λ©΄ μ½”λ“œ 쀑볡과 ν•¨κ»˜ 각 κ³„μΈ΅λ³„λ‘œ μ€‘κ΅¬λ‚œλ°©μœΌλ‘œ κ΅¬ν˜„λœ κ²€μ¦λ‘œμ§κ°„ 뢈일치둜 μΈν•˜μ—¬ 였λ₯˜κ°€ λ°œμƒν•˜κΈ°λ„ 쉽닀.

/posts/images/spring/application-layers.png#center
[좜처] https://docs.jboss.org/hibernate/stable/validator/reference/en-US/html_single/images/application-layers.png

μ΄λŸ¬ν•œ Validation 쀑볡을 ν”Όν•˜κΈ° μœ„ν•΄ λ„λ©”μΈμ˜ 검증 λ‘œμ§μ„ 도메인 λͺ¨λΈ μžμ²΄μ— λ¬Άμ–΄μ„œ μ •μ˜ν•˜κΈ°λ„ ν•œλ‹€. ν•˜μ§€λ§Œ 도메인 λͺ¨λΈμ— μ‹€μ œ μ½”λ“œλ‘œ Validation λ‘œμ§μ„ ν‘œν˜„ν•œλ‹€λ©΄ 도메인 λͺ¨λΈ μžμ²΄κ°€ μž₯ν™©ν•˜μ§€κ³  λ³΅μž‘ν•΄μ§€κ²Œ λœλ‹€.

/posts/images/spring/application-layers2.png#center
[좜처] https://docs.jboss.org/hibernate/stable/validator/reference/en-US/html_single/images/application-layers2.png

Java μ—μ„œλŠ” μœ„μ™€ 같은 문제λ₯Ό ν•΄κ²°ν•˜κΈ° μœ„ν•΄ μ–΄λ…Έν…Œμ΄μ…˜μ„ ν†΅ν•œ Entity 와 Method λ₯Ό κ²€μ¦ν•˜κΈ° μœ„ν•œ API λ₯Ό μ œκ³΅ν•˜κ³  μžˆλ‹€.

Bean Validation

  • μ–΄λ…Έν…Œμ΄μ…˜μ„ 톡해 객체 λͺ¨λΈμ— λŒ€ν•œ μ œμ•½ 쑰건을 ν‘œν˜„ ν•  수 μžˆλ‹€.
  • ν™•μž₯ κ°€λŠ₯ν•œ λ°©μ‹μœΌλ‘œ μ‚¬μš©μž μ •μ˜ μ œμ•½ 쑰건을 μž‘μ„±ν•  수 μžˆλ‹€.
  • 개체 및 개체 κ·Έλž˜ν”„λ₯Ό κ²€μ¦ν•˜κΈ° μœ„ν•œ API λ₯Ό μ œκ³΅ν•œλ‹€.
  • λ©”μ„œλ“œ 및 μƒμ„±μžμ˜ 맀개 λ³€μˆ˜λ₯Ό ν™•μΈν•˜κ³  λ°˜ν™˜ 값을 λ¦¬ν„΄ν•˜λŠ” API λ₯Ό μ œκ³΅ν•œλ‹€.
  • ν˜„μ§€ν™” 된 μ–Έμ–΄λ‘œ μœ„λ°˜ 사항을 λ³΄κ³ ν•œλ‹€.

Hibernate Validator

Hibernate Validator λŠ” Bean Validation λͺ…세에 λŒ€ν•œ κ΅¬ν˜„μ²΄μ΄λ‹€. Bean Validation 2.0 에 λŒ€ν•œ κ΅¬ν˜„μ€ Hibernate Validator 6.0.1.Final 이며 Spring Boot 2.0 μ΄μƒμ—μ„œ 이것을 μ‚¬μš©ν•˜κ³  μžˆλ‹€.

μŠ€ν”„λ§ λΆ€νŠΈλ‘œ Bean Validation μ‹œμž‘ν•˜κΈ°

ν”„λ‘œμ νŠΈ μ„€μ •

Hibernate Validator λŠ” spring-boot-web-start ν”„λ‘œμ νŠΈμ˜ μ˜μ‘΄μ„±μœΌλ‘œ μ •μ˜ λœλ‹€.

  • org.hibernate.validator:hibernate-validator:6.0.13.Final
  • javax.validation:validation-api:2.0.1.Final

컨트둀러 λ©”μ„œλ“œμ— Bean Validation ν™œμ„±ν™”

Controller λ©”μ„œλ“œμ˜ 맀개 λ³€μˆ˜μ— @Valid μ–΄λ…Έν…Œμ΄μ…˜μ„ μΆ”κ°€ν•¨μœΌλ‘œ μœ ν˜€μ„± 검사λ₯Ό 트리거 ν•  수 μžˆλ„λ‘ ν™œμ„±ν™” μ‹œν‚¬ 수 μžˆλ‹€. μ•„λž˜μ˜ 경우 POST μš”μ²­μœΌλ‘œ λ“€μ–΄μ˜¨ λ§€κ°œλ³€μˆ˜λ₯Ό 바인딩 ν•œ λ’€ Todo λΉˆμ— μ •μ˜λœ Validation 에 따라 μœ νš¨μ„± 검증을 ν•˜κ²Œ λœλ‹€.

1
2
3
4
5
6
7
8
9
@RequestMapping(method = RequestMethod.POST, path = "/users/{name}/todos")
public ResponseEntity<?> add(@PathVariable String name, @Valid @RequestBody Todo todo) {
  Todo createTodo = todoService.addTodo(name, todo.getDesc(), todo.getTargetDate(), todo.isDone());
  if(createTodo == null) {
      return ResponseEntity.noContent().build();
  }
  URI location = ServletUriComponentsBuilder.fromCurrentRequest().path("/{id}").buildAndExpand(createTodo.getId()).toUri();
  return ResponseEntity.created(location).build();
}

도메인 객체에 Bean Validation μ •μ˜

1
2
3
4
5
6
7
8
9
public class Todo {
    private int id;
    @NotNull
    private String user;
    @Size(min = 9, message = "Enter at least 10 Characters.")
    private String desc;
    
    // getter setter
}
  • @NotNull - user ν•„λ“œμ˜ 값이 λΉ„μ–΄ μžˆμ§€ μ•Šμ€μ§€ ν™•μΈν•œλ‹€.
  • @Size(min = 9, message = “Enter at least 10 Characters.”) - desc ν•„λ“œ κ°’μ˜ λ¬Έμžκ°€ 9 자 이상인지 ν™•μΈν•œλ‹€.

Bean 을 κ²€μ¦ν•˜λŠ” 데 μ‚¬μš©ν•  수 μžˆλŠ” μ–΄λ…Έν…Œμ΄μ…˜μ€ λ§Žλ‹€. λ‹€μŒμ€ λͺ‡ 가지 Bean Validation μ–΄λ…Έν…Œμ΄μ…˜μ΄λ‹€.

  • @AssertTrue, @AssertFalse - μ–΄λ…Έν…Œμ΄μ…˜ μ •μ˜ 된 ν•„λ“œ 값이 true ν˜Ήμ€ false 인지 확인 ν•œλ‹€.
  • @Future - μ–΄λ…Έν…Œμ΄μ…˜ μ •μ˜ ν•„λ“œ 된 값이 미래 λ‚ μ§œμ—¬μ•Ό ν•œλ‹€.
  • @Past - μ–΄λ…Έν…Œμ΄μ…˜ μ •μ˜ ν•„λ“œ 값이 과거의 λ‚ μ§œμ—¬μ•Ό ν•œλ‹€.
  • @Max - μ–΄λ…Έν…Œμ΄μ…˜ μ •μ˜ ν•„λ“œ 값이 μ§€μ •λœ μ΅œλŒ€κ°’ 보닀 μž‘κ±°λ‚˜ 같은 μˆ«μžμ—¬μ•Ό ν•œλ‹€.
  • @Min - μ–΄λ…Έν…Œμ΄μ…˜ μ •μ˜ ν•„λ“œ 값이 μ§€μ •λœ μ΅œμ†Œκ°’ 보닀 ν¬κ±°λ‚˜ 같은 μˆ«μžμ—¬μ•Ό ν•œλ‹€.
  • @NotNull - μ–΄λ…Έν…Œμ΄μ…˜ μ •μ˜ ν•„λ“œ 값이 null 이면 μ•ˆλœλ‹€.
  • @Pattern - μ–΄λ…Έν…Œμ΄μ…˜ μ •μ˜ ν•„λ“œ κ°’μ˜ {@code CharSequence} μš”μ†ŒλŠ” μ§€μ •λœ μ •κ·œ ν‘œν˜„μ‹κ³Ό μΌμΉ˜ν•΄μ•Ό ν•œλ‹€. μ •κ·œν‘œν˜„μ‹μ€ μžλ°” μ •κ·œ ν‘œν˜„μ‹ κ·œμΉ™μ„ λ”°λ₯Έλ‹€.
  • @Size - μ–΄λ…Έν…Œμ΄μ…˜ μ •μ˜ ν•„λ“œ κ°’μ˜ ν¬κΈ°λŠ” μ§€μ •λœ λ²”μœ„ 내에 μžˆμ–΄μ•Ό ν•œλ‹€.

μ°Έκ³