작성
·
26
·
수정됨
0
[질문 템플릿]
1. 강의 내용과 관련된 질문인가요? 예
2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 아니오
3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예
[질문 내용]
@PostMapping("/add")
public String addItemV1(@ModelAttribute Item item, BindingResult bindingResult, RedirectAttributes redirectAttributes, Model model) {
//검증 오류 결과를 보관
log.info("item.price1 = {}", item.getPrice());
//검증 로직
if (!StringUtils.hasText(item.getItemName())) {
bindingResult.addError(new FieldError("item","itemName","상품 이름은 필수입니다."));
}
if (item.getPrice() == null || item.getPrice() < 1000 || item.getPrice() > 1000000) {
bindingResult.addError(new FieldError("item","price","가격은 1,000 ~ 1,000,000 까지 허용합니다."));
}
if (item.getQuantity() == null || item.getQuantity() >= 9999) {
bindingResult.addError(new FieldError("item", "quantity", "수량은 최대 9,999 까지 허용합니다."));
}
//특정 필드가 아닌 복합 룰 검증
if (item.getPrice() != null && item.getQuantity() != null) {
int resultPrice = item.getPrice() * item.getQuantity();
if (resultPrice < 10000) {
bindingResult.addError(new ObjectError("item","가격 * 수량의 합은 10,000원 이상이어야 합니다. 현재 값 = "+resultPrice));
}
}
//검증에 실패하면 다시 입력 폼으로
if (bindingResult.hasErrors()) {
log.info("errors = {} ", bindingResult);
log.info("item.price2 = {}", item.getPrice());
return "validation/v2/addForm";
}
//성공 로직
Item savedItem = itemRepository.save(item);
redirectAttributes.addAttribute("itemId", savedItem.getId());
redirectAttributes.addAttribute("status", true);
return "redirect:/validation/v2/items/{itemId}";
}
addItemV1에서 폼의 가격에 1원을 입력 후 저장했을 때 log.info("item.price1 = {}",item.getPrice())
와 log.info("item.price2 = {}",item.getPrice())
로 검증시작 전과 검증 실패 후(뷰 반환 직전)에 item.getPrice()의 값을 로그로 확인했는데, 둘다 1이 뜨더라구요.
그럼 검증 실패후 뷰로 넘어갔을 때 뷰에서는 똑같이 1이 남아있어야 하는거 아닌가요? 뷰의 th:field="*{price}"는 item.getPrice()로 값을 가져오는데 왜 1이 아니라 null인건지 이해가 안됩니다..!
-> 강의뒷편에 내용이 나오네요 ㅎㅎ해결했습니다.
답변 1
0
안녕하세요, 인프런 AI 인턴입니다.
질문하신 상황에서 검증 실패 후 뷰
에서 값이 사라지는 이유는 BindingResult와 관련이 있습니다. 스프링 MVC에서 바인딩 오류가 발생하면, 해당 오류가 BindingResult
에 기록되고, 이에 따라 뷰에서 초기 입력값이 사라지는 문제가 발생할 수 있습니다.
주된 이유는 BindingResult
가 값을 초기화하지는 않지만, 뷰에서 타임리프의 th:field
속성이 오류가 발생한 필드의 값을 바인딩 실패 시 빈 값으로 처리하기 때문입니다. 이렇게 되면, 원래 뷰에서 보여주도록 설정된 값이 없기 때문에 화면에서는 검증 실패 시 빈값처럼 나타날 수 있습니다.
이 문제를 해결하기 위해, 검증 실패 시 BindingResult
를 사용하여 사용자가 입력한 값을 뷰에 넘길 수 있게 처리해야 합니다. 만약 스프링 기본 Validator
를 사용 중이라면, 관련 메시지 프로퍼티 파일을 통해 사용자 입력 값을 유지하도록 설정하거나 해당 부분을 커스터마이징하여 값을 유지할 수 있도록 조정할 수 있습니다.
질문에 대한 해결 방법을 더욱 잘理解하고 싶으시다면, 아래의 관련 질문도 참고해 보세요:
BindingResult
에 어떤 값이 저장되는지에 대해 다룹니다.저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.