쌓고 쌓다
[스프링 부트] 유효성 검사 @Validator - 27 본문
기존의 유효성 검사를 위한 코드들을 보자.
컨트롤러에서 유효성 검사를 위한 로직이 차지하는 부분이 크다.
이런 경우는 별도의 클래스로 분리하는 것이 좋다고한다.!
Validator 등록
스프링에서 제공하는 Validator 인터페이스를 살펴보자.
public interface Validator {
boolean supports(Class<?> clazz);
void validate(Object target, Errors errors);
}
- supports : 해당 검증기를 지원하는가 여부 결정
- validate : 검증 대상 target을 통해 유효성 검사 로직을 통해 errors에 담음
PosterValidation
package com.example.board.validation;
import com.example.board.domain.Poster;
import org.springframework.stereotype.Component;
import org.springframework.validation.Errors;
import org.springframework.validation.ValidationUtils;
import org.springframework.validation.Validator;
@Component
public class PosterValidation implements Validator {
@Override
public boolean supports(Class<?> clazz) {
return Poster.class.isAssignableFrom(clazz);
}
@Override
public void validate(Object target, Errors errors) {
Poster poster = (Poster) target;
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "title", "require");
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "writer", "require");
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "content", "require");
if(poster.getHeight()==null || poster.getHeight()<100)
errors.rejectValue("height", "min", new Object[]{100}, null);
if(poster.getWeight()==null || poster.getWeight()<40)
errors.rejectValue("weight", "min", new Object[]{40}, null);
if(poster.getHeight()!=null && poster.getWeight()!=null){
Long height = poster.getHeight();
Long weight = poster.getWeight();
if(height+weight<150)
errors.reject("heightWeightSumMin", new Object[]{150, height+weight}, null);
}
}
}
Validator 사용
PosterValidator를 만들었으니
Controller에서 PosterValidator(검증기)를 직접 호출하여 사용할 수 있다.
@PostMapping("/posters/{category}")
public String write(@PathVariable("category") Category category,
@ModelAttribute Poster poster, BindingResult bindingResult) throws IOException {
// 검증기 직접 호출
posterValidation.validate(poster, bindingResult);
if(bindingResult.hasErrors()) {
return "posters/createPosterForm";
}
}
InitBinder와 WebDataBinder로 사용
Validator를 직접 호출하는 코드를 지울 수 있으며 대신 검증 대상 객체 앞에 @Validated를 붙인다.
@Slf4j
@Controller
@RequiredArgsConstructor
public class PosterController {
private final PosterValidation posterValidation;
@InitBinder("poster")
public void init(WebDataBinder webDataBinder) {
webDataBinder.addValidators(posterValidation);
}
@PostMapping("/posters/{category}")
public String write(@PathVariable("category") Category category,
@Validated @ModelAttribute Poster poster, BindingResult bindingResult) throws IOException {
//posterValidation.validate(poster, bindingResult);
if(bindingResult.hasErrors()) {
System.out.println("bindingResult = " + bindingResult);
return "posters/createPosterForm";
}
}
}
- @InitBinder("poster") : @InitBinder는 해당 컨트롤러에만 영향을 주며 name 속성에 모델명을 주어 검증 객체를 지정한다.
- WebDataBinder : 해당 컨트롤러에서 검증기를 자동으로 적용할 수 있다.
- @Validated : 검증기를 실행하라는 어노테이션으로 검증할 객체에 붙여주자.
- @Validated 어노테이션이 붙어있으면 WebDataBinder에서 검증기를 찾아 supports()를 통해 찾아 수행한다.
- @Validated 대신 @Valid를 사용해도 된다.
- @Validated는 스프링 전용 어노테이션이고, @Valid는 자바 표준 검증 어노테이션이다.
- 검증기 또한 글로벌 설정으로 모든 컨트롤러에 적용 가능하다.
'프로그래밍 > spring' 카테고리의 다른 글
[스프링 부트] 모든 요청 로그 남기기(필터) - 28 (0) | 2023.09.10 |
---|---|
서블릿 필터 (0) | 2023.09.10 |
카카오 로그인 API 및 쿠키 사용하기 (0) | 2023.09.03 |
Set-Cookie가 되었으나 쿠키가 저장이 안될때 (0) | 2023.09.03 |
JSON 데이터 꺼내기 with 중첩된 JSON 다루기 (0) | 2023.09.03 |
Comments