일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- compgen
- 커밋 되돌리기
- @Autowired
- BindingResult
- spring
- JPA
- 기본키 전략
- 편향된 지수
- 쉘 스크립트
- 쿠키
- JDBC
- allocationSize
- 무한정 대기
- 은행원알고리즘
- 파이썬
- 백준
- 티스토리챌린지
- 프로그래머스
- application layer
- 컴파일 타임 상수
- API
- m:n
- 리눅스
- DTO
- 알고리즘
- intelij spring config
- 런타임 상수
- Git
- 오블완
- @SubscribeMapping
- Today
- Total
둘셋 개발!
[Spring] BindResult 객체 본문
BindResult는 Controller 메소드에서 @ModelAttribute에서 객체 바인딩 시 타입 검증에 실패하면 에러정보를 담는 인터페이스이다.
사용예시를 보면,
Item.java
import lombok.Data;
@Data
public class Item {
private Long id;
private String itemName;
private Integer price;
private Integer quantity;
public Item() {
}
public Item(String itemName, Integer price, Integer quantity) {
this.itemName = itemName;
this.price = price;
this.quantity = quantity;
}
}
Controller.java
@PostMapping("/add")
public String addItem3(@ModelAttribute Item item, BindingResult bindingResult, Model model) {
List<FieldError> fieldErrors = bindingResult.getFieldErrors();
for (FieldError error:fieldErrors) {
log.info("error={}", error);
}
/// ...
}
⭐️⭐️ BindingResult는 @ModelAttribute 바로 뒤에 나와야 한다.
http 요청
content-type: multipart/form-data
message body: itemName=iteam1&price=abc&quantity=3
결과 (로그)
error=Field error in object 'item' on field 'price': rejected value [abc];
codes [typeMismatch.item.price,typeMismatch.price,typeMismatch.java.lang.Integer,typeMismatch];
arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [item.price,price];
arguments [];
default message [price]];
default message [Failed to convert property value of type 'java.lang.String' to required type 'java.lang.Integer' for property 'price';
nested exception is java.lang.NumberFormatException: For input string: "abc"]
로그를 보면 어떤 객체(Item)의 어떤 필드(price)가 어떠한 이유(typeMismatich)로 오류가 발생했는지 알 수 있고
어떤 값을 바인딩 하려고 시도했는지도 볼 수 있다.
이렇게 나올 수 있는 이유는 스프링이 @ModelAttribute의 객체에 타입 오류 등으로 바인딩에 실패했을 경우
FieldError를 생성해서 BindingResult에 넣어줬기 때문이다.
여기서 FieldError을 잠깐 살펴볼까?
public class FieldError extends ObjectError {
// 생성자 1
public FieldError(String objectName, String field, String defaultMessage) {
this(objectName, field, null, false, null, null, defaultMessage);
}
// 생성자 2
public FieldError(String objectName, String field, @Nullable Object rejectedValue, boolean bindingFailure,
@Nullable String[] codes, @Nullable Object[] arguments, @Nullable String defaultMessage) {
super(objectName, codes, arguments, defaultMessage);
Assert.notNull(field, "Field must not be null");
this.field = field;
this.rejectedValue = rejectedValue;
this.bindingFailure = bindingFailure;
}
}
- objectName: @ModelAttribute 이름
- field: 오류가 발생한 필드 이름
- defaultMessage: 오류 기본 메세지
- rejectedValue: 거절된 값
- bindingFailure: 타입 오류 실패인지, 검증 실패인지
- codes: 메시지 코드
- arguments: 메세지에서 사용하는 인자
그리고 이렇게 bindingResult가 만들어지면 자동으로 Model에 담겨져서 View로 넘어간다.
이것도 확인해볼까?
Controller.java
@PostMapping("/add")
public String addItem(@ModelAttribute Item item, BindingResult bindingResult, RedirectAttributes redirectAttributes,Model model) {
if (bindingResult.hasErrors()) {
Object result = model.getAttribute("org.springframework.validation.BindingResult.item");
log.info("result={}", result);
}
// ...
}
결과 (로그)
result=org.springframework.validation.BeanPropertyBindingResult: 1 errors
Field error in object 'item' on field 'price': arguments ....(생략)
BeanPropertyBindingResult라는 객체가 model에 담겨있는 것을 확인할 수 있다.
BeanPropertyBindingResult는 인터페이스인 BindingResult를 구현한 구현체이다.
(이미지 출처: https://fordevelop.tistory.com/115)
ref
'SPRING' 카테고리의 다른 글
[SPRING] STOMP @SubscribeMapping 사용법 (0) | 2023.10.15 |
---|---|
[Spring] @Controller사용시 핸들러의 파라미터는 누가 넣어주는 걸까? (0) | 2023.08.18 |
[Spring] RedirectAttributes와 Model차이 (+ addAttribute, addFlashAttribute) (0) | 2023.08.03 |
[오류기록] java.net.SocketException: Invalid argument (0) | 2022.09.05 |