코드 그라데이션
오류 코드와 메시지 처리 (2) 본문
오류 코드와 메시지 처리 (2)
목표
- FieldError , ObjectError 는 다루기 너무 번거롭다.
- 오류 코드도 좀 더 자동화 할 수 있지 않을까? 예) item.itemName 처럼?
컨트롤러에서 BindingResult 는 검증해야 할 객체인 target 바로 다음에 온다.
따라서 BindingResult 는 이미 본인이 검증해야 할 객체인 target 을 알고 있다.
로그 코드를 앞선 메서드에 추가해서 결과를 확인해본다.
@PostMapping("/add")
public String addItemV3(@ModelAttribute Item item,
BindingResult bindingResult,
RedirectAttributes redirectAttributes) {
// 요기 추가
log.info("objectName={}", bindingResult.getObjectName());
log.info("target={}", bindingResult.getTarget());
if (!StringUtils.hasText(item.getItemName())) {
bindingResult.addError(new FieldError("item", "itemName",
item.getItemName(), false, new String[]{"required.item.itemName", "required.default"}, null,
null));
}
if (item.getPrice() == null || item.getPrice() < 1000 || item.getPrice() > 1000000) {
bindingResult.addError(new FieldError("item", "price", item.getPrice(),
false, new String[]{"range.item.price"}, new Object[]{1000, 1000000},
null));
}
if (item.getQuantity() == null || item.getQuantity() > 10000) {
bindingResult.addError(new FieldError("item", "quantity",
item.getQuantity(), false, new String[]{"max.item.quantity"},
new Object[]{9999}, null));
}
// 생략
}
이렇게 알아서 다 들어온다.
rejectValue() , reject()
- BindingResult 가 제공하는 rejectValue() , reject() 를 사용하면 FieldError , ObjectError 를 직접 생성하지 않고, 깔끔하게 검증 오류를 다룰 수 있다.
rejectValue() , reject() 를 사용해서 기존 코드를 단순화해보자.
ValidationItemControllerV2 - addItemV4() 추가
@PostMapping("/add")
public String addItemV4(@ModelAttribute Item item,
BindingResult bindingResult,
RedirectAttributes redirectAttributes) {
log.info("objectName={}", bindingResult.getObjectName());
log.info("target={}", bindingResult.getTarget());
// 에러 검증 코드
if (!StringUtils.hasText(item.getItemName())) {
bindingResult.rejectValue("itemName", "required");
}
if (item.getPrice() == null || item.getPrice() < 1000 || item.getPrice() > 1000000) {
bindingResult.rejectValue("price", "range", new Object[]{1000, 1000000},
null);
}
if (item.getQuantity() == null || item.getQuantity() > 10000) {
bindingResult.rejectValue("quantity", "max", new Object[]{9999},
null);
}
//특정 필드 예외가 아닌 전체 예외
if (item.getPrice() != null && item.getQuantity() != null) {
int resultPrice = item.getPrice() * item.getQuantity();
if (resultPrice < 10000) {
bindingResult.reject("totalPriceMin", new Object[]{10000,
resultPrice}, null);
}
}
if (bindingResult.hasErrors()) {
log.info("errors={}", bindingResult);
return "validation/v2/addForm";
}
//성공 로직
Item savedItem = itemRepository.save(item);
redirectAttributes.addAttribute("itemId", savedItem.getId());
redirectAttributes.addAttribute("status", true);
return "redirect:/validation/v2/items/{itemId}";
}
유의할 점은
- errorCode 영역에 전체를 다 적지 않고, 맨 앞 단어만 적었다는 것이다.
그런데 실행해도 문제없이 잘 작동한다.
rejectValue() 들어가보면
- 생성자는 2개
- 앞에서 BindingResult 는 어떤 객체를 대상으로 검증하는지 target을 이미 알고 있다고 했다. 따라서 target(item)에 대한 정보는 없어도 된다. 오류 필드명은 동일하게 price 를 사용했다.
errors.properties
range.item.price=가격은 {0} ~ {1} 까지 허용합니다.
reject()
물론 생성자가 3개가 있지만,
위의 내용과 논리가 동일하다.
다음 시간에 더 자세히...
728x90
'Spring > Validation' 카테고리의 다른 글
오류 코드와 메시지 처리 (4) (0) | 2024.02.26 |
---|---|
오류 코드와 메시지 처리 (3) (0) | 2024.02.25 |
오류 코드와 메시지 처리 (1) (0) | 2024.02.24 |
FieldError와 ObjectError (0) | 2024.02.23 |
BindingResult 두 번째 (0) | 2024.02.22 |
Comments