🌱 Spring MVC (7) Bean Validation 1 (μž…λ ₯κ°’ 검증 - Bean Validation μ–΄λ…Έν…Œμ΄μ…˜, @Valid, BindingResult)

Kim Dae HyunΒ·2021λ…„ 7μ›” 12일
0

Spring-MVC

λͺ©λ‘ 보기
7/13
post-thumbnail

Github μ†ŒμŠ€μ½”λ“œ

πŸ”Ž Dependencies

BeanValidation을 μœ„ν•œ 쒅속성

[ build.gradle ]
implementation 'org.springframework.boot:spring-boot-starter-validation'

πŸ”Ž Bean 검증 Annotation

자주 μ“°μ΄λŠ” Validation Annotationμž…λ‹ˆλ‹€.
곡식 메뉴얼

public class Item {

    @NotNull
    private Long id;
    
    @NotEmpty(message = "μƒν’ˆλͺ…을 μž…λ ₯ν•΄μ£Όμ„Έμš”.")
    private String itemName;
    
    @NotNull
    @Range(min=1000, max=1000000)
    private Integer price;
    
    @NotNull
    @Range(max=100)
    private Integer quantity;
    
    @DateTimeFormat(pattern = "yyyyMMdd")
    private LocalDate createdAt;
}

πŸ”Ž @Valid

Bean Validationμ—μ„œ κ°€μž₯ ν”νžˆ λ³΄μ΄λŠ” μ–΄λ…Έν…Œμ΄μ…˜λΆ€ν„° μ‚΄νŽ΄λ³Όκ»˜μš”.

  • @ValidλŠ” μš”μ²­ νŒŒλΌλ―Έν„°λ₯Ό λ°”μΈλ”©ν•˜λŠ” 객체 μ•žμ— μœ„μΉ˜ν•©λ‹ˆλ‹€.
    보톡 @ModelAttributeλ‚˜ @RequetParam μ•žμ΄κ² μ£ ?
@PostMapping
public String test(@Valid @ModelAttribute Item item) {
	...
}
  • μ»¨νŠΈλ‘€λŸ¬μ— μœ„μ™€ 같은 λ§€κ°œλ³€μˆ˜κ°€ μžˆλ‹€κ³  ν•˜λ©΄ item 은 μš”μ²­ νŒŒλΌλ―Έν„°λ‘œ 바인딩 되고 @Valid에 μ˜ν•΄ Item ν΄λž˜μŠ€μ— μ§€μ •λœ 검증 둜직이 λ™μž‘ν•˜λŠ” 것 μž…λ‹ˆλ‹€.
  • 그럼 검증 κ²°κ³ΌλŠ” μ–΄λ–»κ²Œ 확인할 수 μžˆμ„κΉŒμš”?

πŸ”Ž BindingResult

@Valid에 μ˜ν•΄ κ²€μ¦λœ κ²°κ³ΌλŠ” BindingResult에 μ €μž₯λ©λ‹ˆλ‹€.
이름 κ·ΈλŒ€λ‘œ 검증 κ²°κ³Όκ°€ 바인딩 λœλ‹€κ³  이해해도 될 것 κ°™μ•„μš”.

@PostMapping
public String add(
	@Valid @ModelAttribute Item item, 
    	BindingResult bindingResult) {

    if (bindingResult.hasErrors()) {
        log.info("binding result = {}", bindingResult);
        return "form"; // ν˜„μž¬ 폼을 λ‹€μ‹œ λžœλ”λ§
    }

    log.info("****** λΉ„μ¦ˆλ‹ˆμŠ€λ‘œμ§ μˆ˜ν–‰ ********");
	
    // 둜직 μ„±κ³΅μ‹œ μš”κ΅¬μ‚¬ν•­ λŒ€λ‘œ redirect λ˜λŠ” viewλ₯Ό λžœλ”λ§
    return "form";
}
  • BindingResultλŠ” λ§€κ°œλ³€μˆ˜λ‘œ λ°›κ²Œ λ˜λŠ”λ° μœ„μΉ˜κ°€ μ€‘μš”ν•©λ‹ˆλ‹€.
    κ²€μ¦ν•˜κ³ μž ν•˜λŠ” 객체의 λ°”λ‘œ λ‹€μŒμ— μœ„μΉ˜ν•΄ μ€˜μ•Ό ν•΄μš”.
  • @Valid에 μ˜ν•΄ 였λ₯˜κ°€ λ°œμƒν–ˆλŠ”μ§€ 여뢀와 μ—λŸ¬κ°€ λ°œμƒν•œ κ°’, μ—λŸ¬ μ½”λ“œ 등이 BindingResult에 바인딩 λ©λ‹ˆλ‹€.
  • κ²€μ¦μ˜€λ₯˜κ°€ λ°œμƒν–ˆλ‹€λ©΄ bindingResult.hasError()λŠ” trueλ₯Ό λ¦¬ν„΄ν•©λ‹ˆλ‹€.
  • λ˜ν•œ @ModelAttribute에 μ˜ν•΄ Model에 값이 바인딩 될 λ•Œ κ²€μ¦μ—λŸ¬ 값도 ν•¨κ»˜ 바인딩 λ©λ‹ˆλ‹€. 그럼 Viewλ‹¨μ—μ„œ λ°”λ‘œ 검증 였λ₯˜ λ©”μ‹œμ§€λ₯Ό μ‚¬μš©μžμ—κ²Œ 보여쀄 수 있겠죠?

πŸ”Ž Viewλ‹¨μ—μ„œ κ²€μ¦μ˜€λ₯˜ λ©”μ‹œμ§€ λ‚˜νƒ€λ‚΄κΈ° (Thymeleaf)

μƒν’ˆμ΄λ¦„(itemName)κ³Ό μƒν’ˆκ°€κ²©(price) 두 값을 μž…λ ₯λ°›λŠ” νΌμž…λ‹ˆλ‹€.
νΌμ—μ„œ /test둜 post μš”μ²­μ„ μˆ˜ν–‰ν•˜κ³  ν•΄λ‹Ή μ»¨νŠΈλ‘€λ‘œμ—μ„œ 검증 ν›„ 검증 κ²°κ³Όλ₯Ό Model에 λ‹΄μ•„ 였λ₯˜κ°€ μžˆλ‹€λ©΄ μ•„λž˜ 폼을 λ‹€μ‹œ λžœλ”λ§ ν•©λ‹ˆλ‹€.

  • κ²€μ¦μ˜€λ₯˜ λ°œμƒμ‹œ λ‹€μ‹œ λžœλ”λ§ λ˜μ—ˆμ„ λ•Œ th:errors둜 ν•΄λ‹Ή ν•„λ“œμ— 였λ₯˜κ°€ μžˆλŠ”μ§€ κ²€μ‚¬ν•˜κ³  μžˆλ‹€λ©΄ μ§€μ •λœ μ—λŸ¬ λ©”μ‹œμ§€λ₯Ό λ‚˜νƒ€λƒ…λ‹ˆλ‹€.
  • th:errorclass μ§€μ •ν•œ μ΄λ¦„μ˜ ν•„λ“œμ—μ„œ κ²€μ¦μ˜€λ₯˜ λ°œμƒμ‹œ μž„μ˜ classλ₯Ό μΆ”κ°€ν•©λ‹ˆλ‹€. μ˜ˆμ œμ—μ„œλŠ” 클래슀둜 μ •μ˜ν•œ cssλ₯Ό κ²€μ¦μ˜€λ₯˜ λ°œμƒμ‹œ μΆ”κ°€ν•΄μ€λ‹ˆλ‹€.
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .field-error {
            border-color: red;
            color: red;
        }
    </style>
</head>
<body>
<form th:action="test" th:object="${item}" method="post">

    <label for="itemName"/>
    <input type="text" id="itemName" th:field="*{itemName}" th:errorclass="itemName">
    <div th:errors="*{itemName}" class="field-error"></div>
    <br/>

    <label for="price"/>
    <input type="text" id="price" th:field="*{price}" th:errorclass="price">
    <div th:errors="*{price}" class="field-error"></div>
    <br/>

    <button type="submit">등둝</button>
</form>
</body>
</html>

아무것도 μž…λ ₯ν•˜μ§€ μ•Šμ€ μƒνƒœμ—μ„œ μ„œλ²„λ‘œ μ „μ†‘ν–ˆμ„ λ•Œμ˜ View κ²°κ³Όμž…λ‹ˆλ‹€.

μƒν’ˆλͺ…μ˜ 경우 Item의 @NotEmptyμ—μ„œ 지정해쀀 λ©”μ‹œμ§€κ°€ λ‚˜μ™”κ³  κ°€κ²©μ˜ 경우 @NotNull을 μ§€μ •ν•˜κ³  λ©”μ‹œμ§€λ₯Ό μ§€μ •ν•˜μ§€ μ•Šμ•˜κΈ° λ•Œλ¬Έμ— Springμ—μ„œ μ§€μ •ν•œ default λ©”μ‹œμ§€κ°€ λ‚˜μ™”μŠ΅λ‹ˆλ‹€.

profile
μ’€ 더 천천히 까먹기 μœ„ν•΄ κΈ°λ‘ν•©λ‹ˆλ‹€. 🧐

1개의 λŒ“κΈ€

comment-user-thumbnail
2022λ…„ 6μ›” 23일

μ„ μƒλ‹˜ 이런 지식은 μ–΄λ””μ„œ λ΄μ„œ μ•Œκ³ κ³„μ‹ κ±΄κ°€μš”? bindingresultλŠ” λ§€κ°œλ³€μˆ˜ λ°”λ‘œ λ‹€μŒμ— μ˜€λŠ” 이런 μ§€μ‹μ΄μš” κΆκΈˆν•©λ‹ˆλ‹€

λ‹΅κΈ€ 달기