javax.validation.constraints 패키지에 있는 검증 어노테이션을 사용해서 객체 값에 대한 유효성 검증을 해보려고 한다.
build.gradle에 spring-boot-starter-validation을 추가해준다.
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-validation'
}
javax.validation.constraints에서 제공되는 어노테이션은 굉장히 많은데 그 중에서도 @NotEmpty, @NotNull을 사용해서 유효성 검증을 해보려 한다. @NotEmpty는 String 타입에 사용되며 Integer의 경우에는 @NotNull을 사용한다.
import lombok.Data;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
@Data
public class Item {
private Long id;
@NotEmpty(message = "필수 입력란입니다")
private String itemName;
@NotNull(message = "필수 입력란입니다")
private Integer price;
@NotNull(message = "필수 입력란입니다")
private Integer quantity;
public Item(){}
public Item(String itemName, Integer price, Integer quantity) {
this.itemName = itemName;
this.price = price;
this.quantity = quantity;
}
}
값이 들어오지 않을 경우 message로 내용을 전달해준다.
@Controller
@RequiredArgsConstructor
@RequestMapping("/items")
public class ItemController {
private final ItemService itemService;
@GetMapping
public String items(@ModelAttribute("searchCondition") SearchCondition searchCondition, Model model){
List<Item> items = itemService.findAll(searchCondition);
model.addAttribute("items", items);
return "items";
}
@GetMapping("/add")
public String addForm(Item item, Model model){
model.addAttribute("item", item);
return "addForm";
}
@PostMapping("/add")
public String addItems(@Valid @ModelAttribute("item") Item item, BindingResult result){
if(result.hasErrors()) {
return "addForm";
}
itemService.save(item);
return "redirect:/items";
}
}
요청이 들어오는 Item 객체 앞에 @Valid 어노테이션을 붙여서 객체에 들어가는 값을 검증한다. @Valid 어노테이션을 통해서 @Size,@Email, @NotNull 등을 사용해 간단하게 값을 검증할 수 있다.
binding error가 발생할 경우 화면단에서 에러 메시지를 표시해주기 위해 뷰 템플릿에도 동일한 작업을 진행해준다. 뷰 템플릿은 타임리프를 사용했다.
<form th:action="@{/items/add}" th:object="${item}" method="post">
<div class="alert alert-dismissible alert-light">
<div class="form-group">
<label for="itemName" class="form-label mt-4 fs-3">상품명</label>
<input type="text" th:field="*{itemName}" id="itemName" name="itemName"
aria-describedby="emailHelp" th:class="${#fields.hasErrors('itemName')}? 'form-control fieldError' : 'form-control'" placeholder="상품명을 입력하세요">
<small id="emailHelp" class="form-text text-muted">정확한 상품명을 입력해주세요</small>
<p th:if="${#fields.hasErrors('itemName')}"
th:errors="*{itemName}" th:class="${#fields.hasErrors('quantity')}? 'messageError' : ''">Incorrect date</p>
</div>
값이 들어오지 않으면 에러메시지를 표시해준다.
값을 입력하지 않으면 미리 설정해둔 메시지가 뜨는 것을 확인할 수 있다.