일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- html form
- 다형성
- 코딩테스트
- HttpServletResponse
- http 메시지 컨버터
- 인터페이스
- 티스토리챌린지
- JSON
- @configuration
- fielderror
- 김영한
- 프록시
- 테스트코드
- 추상클래스
- 스프링
- objecterror
- ocp
- equals()
- 오버라이딩
- 코드트리조별과제
- 의존관계
- 백준
- 오블완
- java
- 서블릿
- 스프링컨테이너
- DI
- 코드트리
- 참조변수
- 싱글톤
- Today
- Total
minOS
Validation - BindingResult 본문
스프링이 제공하는 검증 오류 처리 방법
BindingResult
스프링이 제공하는 검증 오류를 보관하는 객체이다. 검증 오류가 발생하면 여기에 보관하면 된다. `BindingResult` 가 있으면`@ModelAttribute` 에 데이터 바인딩 시 오류가 발생해도 컨트롤러가 호출된다
ex) @ModelAttribute에 바인딩 시 타입 오류가 발생하면?**
`BindingResult` 가 없으면 400 오류가 발생하면서 컨트롤러가 호출되지 않고, 오류 페이지로 이동한다. `BindingResult` 가 있으면 오류 정보( `FieldError` )를 `BindingResult` 에 담아서 컨트롤러를 정상 호출한다.
BindingResult에 검증 오류를 적용하는 3가지 방법
- @ModelAttribute` 의 객체에 타입 오류 등으로 바인딩이 실패하는 경우 스프링이 `FieldError` 생성해서 `BindingResult` 에 넣어준다.- 개발자가 직접 넣어준다.
- Validator` 사용 이것은 뒤에서 설명
입력폼에 아무것도 입력하지 않고 상품 등록 폼을 저장해도 오류 페이지로 가지 않고 오류 메세지를 출력해주는 것을 알 수 있다.주의
- BindingResult는 검증할 대상 바로 다음에 와야한다. 순서가 중요하다. 예를 들어서 `@ModelAttribute Item item` , 바로 다음에 `BindingResult` 가 와야 한다.
- BindingResult` 는 Model에 자동으로 포함된다.
BindingResult와 Errors
BindingResult` 는 인터페이스이고, `Errors` 인터페이스를 상속받고 있다.
실제 넘어오는 구현체는 `BeanPropertyBindingResult` 라는 것인데, 둘다 구현하고 있으므로 `BindingResult` 대신에 `Errors` 를 사용해도 된다. `Errors` 인터페이스는 단순한 오류 저장과 조회 기능을 제공한다. `BindingResult` 는 여기에 더해서 추가적인 기능들을 제공한다. `addError()` 도 `BindingResult` 가 제공하므 로 여기서는 `BindingResult` 를 사용하자. 주로 관례상 `BindingResult` 를 많이 사용한다.
BindingResult 사용한 검증 코드
@PostMapping("/add") //`BindingResult bindingResult` 파라미터의 위치는 `@ModelAttribute Item item` 다음에 와야 한다. public String addItemV1(@ModelAttribute Item item, BindingResult bindingResult ,RedirectAttributes redirectAttributes, Model model) { // bindReuslt = errors 와 같은 기능 ,검증 오류 결과를 보관 //검증 로직 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("error ={}", bindingResult); //model.addAttribute("errors",errors); BindResult는 자동으로 view로 넘어감 return "/validation/v2/addForm"; } // 성공 로직 Item savedItem = itemRepository.save(item); redirectAttributes.addAttribute("itemId", savedItem.getId()); redirectAttributes.addAttribute("status", true); return "redirect:/validation/v2/items/{itemId}"; }
남은 문제점
가격과 수량에서 오류 메세지를 띄우겠지만 사용자가 입력한 값이 남아있어야 중복되는 오류를 막기 쉽다.
현재는 저장 버튼을 누르면 입력값이 남아있지 않는다. 이러한 문제를 해결하려면 FieldError, ObjectError를 더 활용하면 된다.
'TIL > 김영한의 스프링 MVC 2편 - 백엔드 웹 개발 핵심 기술' 카테고리의 다른 글
오류 코드와 메세지 처리 (7) | 2024.09.13 |
---|---|
Validation - FieldError, ObjectError (4) | 2024.09.11 |
Validation - 검증 직접 처리 (3) | 2024.09.11 |
메세지,국제화 (6) | 2024.09.09 |
타임리프 스프링 통합 - 입력 폼 처리 (6) | 2024.08.30 |