- Spring MVC 마스터하기 Validation 32022년 05월 08일
- starryeye
- 작성자
- 2022.05.08.:51
BindingResult
스프링에서 제공하는 invalid 값이 넘어왔을 때, invalid 값들을 보관하는 객체이다.
해당 컨트롤러에 BindingResult 객체가 @ModelAttribute 파라미터 다음 파라미터로 존재하면, 해당 @ModelAttribute 데이터 바인딩 시 오류가 발생해도 컨트롤러가 호출된다.
위 예시와 같이 @ModelAttribute로 받는 Item 파라미터 다음으로 BindingResult 객채 파라미터가 있어서
타입에러와 같이 Item 바인딩시 오류가 나도 컨트롤러 호출 전에 400 에러 페이지로 가지 않고, 해당 컨트롤러가 호출된다.
<정리 - price 필드에 문자를 넣고 등록했을 경우>
BindingResult 가 없다
-> 400 오류가 발생하면서 컨트롤러가 호출 되지 않고, 오류 페이지로 이동한다.
BindingResult 가 있다
-> 오류 정보(FieldError)를 BindingResult에 담아서 컨트롤러를 정상 호출 한다.
FieldError
필드에 오류가 있을 때, FieldError 객체를 생성하여 BindingResult 객체에 담을 수 있다.
FieldError 인터페이스 위 코드는 FieldError의 인터페이스이다.
생성자는 2가지가 있다.
각 파라미터를 알아보자.
objectName : 매칭되는 @ModelAttribute 이름
field : 오류가 발생된 필드 이름
defaultMessate : 오류가 났을 시, 출력되는 메세지
rejectedValue : invalid 데이터를 담을 수 있는 보관소
bindingFailure : 타입오류 같은 바인딩 실패인지(true), 사용자가 정의한 값의 범위를 벗어난 실패인지(false)
codes : 메세지 코드
arguments : 메세지에서 사용하는 인자
타입 에러는 스프링에서 자동으로 처리해준다.
가장 위 addItemV2 controller 예시를 보면, price 필드의 경우 null 체크와 값의 범위만 체크해주고있다.
그러나, 실제로 실행하여 문자를 넣어줘도 에러페이지로 가지 않고 컨트롤러가 호출되어 addForm 페이지로 간다.
이유를 알아보자.
타입오류(문자를 넣음) 같은 바인딩이 실패한 경우 컨트롤러 호출전에 실패가 난다.
(컨트롤러 파라미터로 BindingResult 객체를 받기 때문에 컨트롤러 호출은 될 것이다.)
스프링이 BindingResult 객체에 FieldError 객체를 미리 넣어준다.
rejectedValue 자리에 실패하게된 문자열을 넣는다.
bindingFailure 자리에는 true를 넣는다.
따라서 컨트롤러 호출전에 이미 FieldError 객체가 하나 들어가 있는 상태로 시작되는 것이다.
그러면서 컨트롤러 코드에서는 price 필드에는 null 값이니까..
범위가 잘못되었다는 오류 메세지가 출력된다.
(타입에러에 대한 오류메세지는 스프링에서 자체적으로 생성한 오류메세지가 넣어져있음)
-> 2가지의 오류메세지가 출력됨.
<타임리프>
th:field="*{price}"
타임리프의 th:field는 정상 상황에서는 모델 객체의 값을 사용한다.
(model의 item객체에 있는 getprice)
오류가 발생하면 FieldError에서 보관되어있는 값을 사용하여 출력한다.
(오류가 나게된 값)
개발자가 정의한 범위에 대한 오류 처리
price 필드에 숫자 1을 넣었을 경우... (범위 : 1000~1000000)
역시 가장 위 addItemV2 controller 예시를 보면된다.
타입에러가 아니기 때문에 컨트롤러 호출전에 BindingResult 에는 FieldError 객체가 저장되어있지 않게 된다.
그러나 ...
컨트롤러 내부 코드에서 FieldError 객체를 생성하여 넣어주고있다.
rejectValue 자리에는 바인딩에 성공한 item객체의 price값 (item.getPrice())
bindingFailure 자리에는 false이다.
ObjectError
BindingResult 객체에는 ObjectError 객체도 넣을 수 있다.
특정 필드의 오류가 아닌 복합 오류일때 사용 가능하다.
(ex. price * quantity 의 값은 특정 범위 여야 한다.)
위 코드는 ObjectError 인터페이스의 생성자이다.
FieldError 에서 있었던 field, rejectValue, bindingFailure 파라미터가 안보인다.
-> 애초에 사용자가 전달한 특정 필드에 대한 오류를 처리하는 객체가 아니기 때문임.
'Spring > MVC' 카테고리의 다른 글
Spring MVC 마스터하기 Validation 5 (0) 2022.05.17 Spring MVC 마스터하기 Validation 4 (0) 2022.05.17 Spring MVC 마스터하기 Validation 2 (0) 2022.05.08 Spring MVC 마스터하기 Validation 1 (0) 2022.05.08 Spring MVC Redirect, PRG (0) 2022.05.06 다음글이전글이전 글이 없습니다.댓글