스프링이 제공하는 검증 오류 처리 방법중에 BindingResult를 이용해서 처리한다.
BindingResult를 사용하면서 가장 중요한것은
BindingResult bindingResult
파라미터 위치는 @ModelAttribute Item item
다음에 와야 한다.
안그러면 오류터진다. 내가 터져봄
필드에 오류가 있으면 FieldError
객체를 생성해서 bindingResult
에 담아두면 된다.
objectName
: @ModelAttribute
이름field
: 오류가 발생한 필드 이름defaultMessage
: 오류 기본 메시지글로벌 오류는 ObjectError
를 넣으면 된다.
bindingResult.addError(new ObjectError("item", "오류 내용"))
원래 bindingResult.addError()
파라미터는 ObjectError
타입이 들어가는데 FieldError
는 ObjectError
의 자식이라 둘 다 들어갈 수 있다.
크게 중요하진 않음.
ObjectError
는 item
이라는 오브젝트 자체에 오류가 있다는 뜻.
FieldError
는 item
안의 필드에 오류가 있다는 뜻.
이전 버전과 다르게 더 단순화된 모습을 확인할 수 있다.
타임리프는 스프링의 BindingResult
를 효율적으로 사용할 수 있도록 제공을 해준다.
#fields
: #fields
로 BindingResult
로 접근할 수 있다.
th:errors
: 해당 필드에 오류가 있다면 태그를 출력한다.
th:errorclass
: th:field
에서 오류가 있으면 class
정보를 추가한다.
검증과 오류 메시지 공식 메뉴얼
https://www.thymeleaf.org/doc/tutorials/3.0/thymeleafspring.html#validation-and-error-messages
먼저 BindingResult
는 인터페이스이고, Errors
인터페이스를 상속받고 있다.
실제 넘어오는 구현체는 BeanPropertyBindingResult
라는 것인데, 둘다 구현하고 있으므로 BindingResult
대신 Errors
써도 됨.
근데 BindingResult
가 더 좋은게 많으니 이거 쓰자. 관례상 BindingResult
를 많이 사용하기도 함.
그리고 만약 위와 같이 작성하면 실패했을때 값이 남지 않는다.
예를들어 수량을 너무 적게 입력했다면 폼으로 다시 보내졌을때 수량이 지워진다.
남게 하기 위해서는 파라미터 정보를 두 번째줄에 있는 방식으로 적어야 한다.
파라미터 목록
objectName
: 오류가 발생한 객체 이름 item
field
: 오류 필드 itemName
refectedValue
: 사용자가 입력한 값(거절된 값) item.getItemName()
bindingFailure
: 타입 오류 같은 바인딩 실패인지, 검증 실패인지 구분 값 false
codes
: 메시지 코드 null
arguments
: 메시지에서 사용하는 인자 null
defaultMessage
: 기본 오류 메시지 상품 이름~
자 그러면 어떻게 오류 발생시 사용자 입력 값이 유지되는 걸까
위에서 언급했던 Integer 타입에 String이 들어갈때 다른 타입의 형식이 들어왔는데 어떻게 입력값을 유지할 수 있을까
FieldError
가 해준다.
정확히는 스프링이 컨트롤러를 불러오기전에 FieldError
의 파라미터 목록 중에 refectedValue
에 사용자가 입력했던 값을 그대로 넣어주고 컨트롤러를 불러오기 때문에 별다른 예외발생 없이 코드가 진행된다.
타임리프에서 th:field
도 엄청난 역할을 하는데
정상 상황에서는 모델 객체의 값을 사용하지만, 오류가 발생하면 FieldError
에 보관한 값을 사용해서 값을 출력한다.