일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 이분탐색
- 그리드
- 분할 정복
- TCP
- GIT
- 역방향 반복자
- 알고리즘
- 그리드 알고리즘
- Spring
- 재귀
- 다이나믹프로그래밍
- 컴퓨터 네트워크
- 스프링
- 트리
- SQL
- AWS
- 백준
- dfs
- 분할정복
- BFS
- CI/CD
- github action
- 그래프
- 다이나믹 프로그래밍
- 도커
- 순열
- 브루트포스
- 자료구조
- HTTP
- 자바
- Today
- Total
코딩성장스토리
스프링 vaildation 본문
김영한 선생님의 MVC2편 정리
검증
HTTP 요청이 정상인지 우리의 요구랑 다른 값들이 들어오는지 검증하는 단계이고 스프링에서 도와주는 기능들이 있다.
오류 처리 방법을 도와주는 BindingResult
BindingResult bindingResult 파라미터의 위치는 @ModelAttribute Item item 다음에 와야 한다 이렇게 하면 BIndingResult는 객체 item을 알고 있고 사용이 가능하다
필드오류(fielderror)
if (!StringUtils.hasText(item.getItemName())) {
bindingResult.addError(new FieldError("item", "itemName", "상품 이름은
필수입니다."));
}
파라미터 목록
objectName : 오류가 발생한 객체 이름
field : 오류 필드
rejectedValue : 사용자가 입력한 값(거절된 값)
bindingFailure : 타입 오류 같은 바인딩 실패인지, 검증 실패인지 구분 값
codes : 메시지 코드 -메시지 코드는 전에 했던 메시지,국제화 사용하듯이 errors.properties에 넣어서 사용함
arguments : 메시지에서 사용하는 인자
defaultMessage : 기본 오류 메시지
글로벌 오류 - ObjectError
bindingResult.addError(new ObjectError("item", "가격 * 수량의 합은 10,000원 이상이어야
합니다. 현재 값 = " + resultPrice));
특정 필드를 넘어서는 오류가 있으면 ObjectError 객체를 생성해서 bindingResult 에 담아두면 된다.
파라미터는 필드오류 랑 유사하다
타임리프 스프링 검증 오류 통합 기능
타임리프는 스프링의 BindingResult 를 활용해서 편리하게 검증 오류를 표현하는 기능을 제공한다.
- #fields : #fields 로 BindingResult 가 제공하는 검증 오류에 접근할 수 있다.
- th:errors : 해당 필드에 오류가 있는 경우에 태그를 출력한다. th:if 의 편의 버전이다.
- th:errorclass : th:field 에서 지정한 필드에 오류가 있으면 class 정보를 추가한다
BindingResult에 검증 오류를 적용하는 3가지 방법
- @ModelAttribute 의 객체에 타입 오류 등으로 바인딩이 실패하는 경우 스프링이 FieldError 생성해서 BindingResult 에 넣어준다.
- 개발자가 직접 넣어준다.
- Validator 사용
오류 발생시 사용자 입력 값 유지
new FieldError("item", "price", item.getPrice(), false, null, null, "가격은 1,000 ~ 1,000,000 까지 허용합니다."
하지만 이럴 경우 타입이 안 맞으면 객체에 저장이 불가능 하다.
하지만 th:field="*{price}" 타임리프의 th:field 는 매우 똑똑하게 동작하는데, 정상 상황에는 모델 객체의 값을 사용하지만, 오류가 발생하면 FieldError 에서 보관한 값을 사용해서 값을 출력한다
하지만 위와 같은 필드 오류와 글로벌 오류를 다루기는 인자가 많기도 하고 중복이 많다 이를 편히 만든게
rejectValue()
BindingResult 가 제공하는 rejectValue()를 사용하면 FieldError , ObjectError 를 직접 생성하지 않고, 깔끔하게 검증 오류를 다룰 수 있다.
void rejectValue(@Nullable String field, String errorCode,
@Nullable Object[] errorArgs, @Nullable String defaultMessage);
field : 오류 필드명
errorCode : 오류 코드(이 오류 코드는 메시지에 등록된 코드가 아니다.
errorArgs : 오류 메시지에서 {0} 을 치환하기 위한 값
defaultMessage : 오류 메시지를 찾을 수 없을 때 사용하는 기본 메시지
위에가 가능한 이유는 BindingResult가 이미 바인딩할 객체를 알고 있고 위의 오류코드를 단순하게
FieldError rejectValue("itemName", "required") 적용이 가능하다 .이유는
다음 4가지 오류 코드를 자동으로 생성하고 위에서 부터 우선순위가 적용이 된다.
required.item.itemName
required.itemName
required.java.lang.String
required
ObjectError reject("totalPriceMin")
다음 2가지 오류 코드를 자동으로 생성
totalPriceMin.item
totalPriceMin
하지만 위의 기능들은 타입이 다른것들을 오류처리할 수 없다
스프링은 타입 오류가 발생하면 typeMismatch 라는 오류 코드를 사용한다
typeMismatch.item.price
typeMismatch.price
typeMismatch.java.lang.Integer
typeMismatch
위의 메시지 코드를 정리하면 타입이 다른 것들도 오류처리가 가능하다.
검증 부분 분리하기
이떄 쓰이는 인터페이스
public interface Validator {
boolean supports(Class<?> clazz);
void validate(Object target, Errors errors);
}
supports() {} : 해당 검증기를 지원하는 여부 확인(뒤에서 설명)
validate(Object target, Errors errors) : 검증 대상 객체와 BindingResult (errors가 binding Result 상위클래스)
WebDataBinder 는 스프링의 파라미터 바인딩의 역할을 해주고 검증 기능도 내부에 포함한다.
컨트롤러에 포함하면 검증기 전부 사용가능
@InitBinder
public void init(WebDataBinder dataBinder) {
log.info("init binder {}", dataBinder);
dataBinder.addValidators(itemValidator);
}
@Validated 는 검증기를 실행하라는 애노테이션이다.
이 애노테이션이 붙으면 앞서 WebDataBinder 에 등록한 검증기를 찾아서 실행한다.
그런데 여러 검증기를 등록한다면 그 중에 어떤 검증기가 실행되어야 할지 구분이 필요하다.
이때 supports() 가 사용된다. 여기서는 supports(Item.class) 호출되고, 결과가 true 이므로 ItemValidator 의 validate() 가 호출된다
@PostMapping("/add")
public String addItem(@Validated @ModelAttribute("item") ItemSaveForm form,
BindingResult bindingResult, RedirectAttributes redirectAttributes) {
//...
}
위 코드처럼 검증할 객체앞에 @vaildated 붙이기
'백 엔드 > spring' 카테고리의 다른 글
스프링 -쿠키,세션 (0) | 2022.05.13 |
---|---|
스프링 Bean Validation (0) | 2022.05.09 |
스프링 메시지,국제화 (0) | 2022.05.06 |
스프링 타임리프 스프링 통합기능 (0) | 2022.05.06 |
spring 타임리프 기본기능 (0) | 2022.05.05 |