BeanValidationμ μν μ’ μμ±
[ build.gradle ]
implementation 'org.springframework.boot:spring-boot-starter-validation'
μμ£Ό μ°μ΄λ 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;
}
Bean Validationμμ κ°μ₯ νν 보μ΄λ μ΄λ Έν μ΄μ λΆν° μ΄ν΄λ³Όκ»μ.
@Valid
λ μμ² νλΌλ―Έν°λ₯Ό λ°μΈλ©νλ κ°μ²΄ μμ μμΉν©λλ€.@ModelAttribute
λ @RequetParam
μμ΄κ² μ£ ?@PostMapping
public String test(@Valid @ModelAttribute Item item) {
...
}
item
μ μμ² νλΌλ―Έν°λ‘ λ°μΈλ© λκ³ @Valid
μ μν΄ Item
ν΄λμ€μ μ§μ λ κ²μ¦ λ‘μ§μ΄ λμνλ κ² μ
λλ€.@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λ¨μμ λ°λ‘ κ²μ¦ μ€λ₯ λ©μμ§λ₯Ό μ¬μ©μμκ² λ³΄μ¬μ€ μ μκ² μ£ ?μνμ΄λ¦(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 λ©μμ§κ° λμμ΅λλ€.
μ μλ μ΄λ° μ§μμ μ΄λμ λ΄μ μκ³ κ³μ 건κ°μ? bindingresultλ 맀κ°λ³μ λ°λ‘ λ€μμ μ€λ μ΄λ° μ§μμ΄μ κΆκΈν©λλ€