티스토리 뷰
스프링 MVC에는 모든 컨트롤러에 적용할 수 있는 글로벌 범위 Validator 와 단일 컨트롤러에 적용할 수 있는 Validator를 설정하는 방법이 있다.
글로벌 범위 Validator (@Valid)
글로벌 범위 Validator는 모든 컨트롤러에 적용할수 있는 Validator 이다.
글로벌 범위 Validator를 적용하려면 다음 두 가지를 설정해야 한다.
1. 설정 클래스에서 WebMvcConfigurer의 getValidator() 메서드가 Validator 구현 객체를 리턴하도록 구현
package config;
// ..
// Spring MVC 설정
@Configuration
@EnableWebMvc
public class MvcConfig implements WebMvcConfigurer
{
// .. 생략
// 스프링은 getValidator()가 리턴한 객체를 글로벌 범위 Validator로 사용
@Override
public Validator getValidator()
{
return new RegisterRequestValidator();
}
}
2. 글로벌 범위 Validator가 검증할 커맨드 객체에 @Valid 애노테이션 적용
package controller;
// ..
@Controller
public class RegisterController
{
// ..
// 회원가입 form 데이터 받아서 처리하고 step3 (회원가입 완료 페이지) 이동
@PostMapping("/register/step3")
public String handleStep3(@Valid RegisterRequest regReq, Errors errors)
{
// 에러 있다면 step2 로 되돌아감
// @Valid에서 처리
// new RegisterRequestValidator().validate(regReq, errors);
if(errors.hasErrors()) return "register/step2";
// ..
}
}
커맨드 객체 ReigsterRequest 앞에 @Valid 애노테이션을 붙여 적용했다.
이렇게 되면 @Valid 애노테이션에 의해 Validator가 해당 타입을 검증할수 있는지 확인하고 (RegisterRequestValidator의 supports 메서드), 에러가 있는지 확인한다 (validate 메서드) .
위 과정은 요청 처리 메서드 (handleStep3) 실행 전에 수행된다.
컨트롤러 범위 Validator (@InitBinder)
특정 컨트롤러를 검사할 Validator의 설정은 다음과 같이 할수 있다.
package controller;
// ...
@Controller
public class RegisterController
{
// ...
// 회원가입 form 데이터 받아서 처리하고 step3 (회원가입 완료 페이지) 이동
@PostMapping("/register/step3")
public String handleStep3(@Valid RegisterRequest regReq, Errors errors)
{
// 에러 있다면 step2 로 되돌아감
// @Valid에서 처리
// new RegisterRequestValidator().validate(regReq, errors);
if(errors.hasErrors()) return "register/step2";
try
{
memberRegisterService.regist(regReq);
return "register/step3";
} catch(DuplicateMemberException ex)
{
errors.rejectValue("email", "duplicate");
return "register/step2";
}
}
// @Valid 가 붙은 커맨드 객체 검사할 Validator 설정
// 컨트롤러의 요청 처리 메서드 실행 전 매번 실행
@InitBinder
protected void initBinder(WebDataBinder binder)
{
binder.setValidator(new RegisterRequestValidator());
}
}
handleStep3 메서드의 파라미터에 커맨드 객체 RegisterRequest 앞에 @Valid 애노테이션을 붙였다.
그리고 @InitBinder가 붙은 initBinder 메서드에서 WebDataBinder#setValidator()로 RegisterRequestValidator를 등록하고 있다.
이것은 RegisterReqeust 객체를 검사할 Validator를 RegisterRequestValidator로 지정하겠다는 의미이다.
@InitBinder가 붙은 메서드는 컨트롤러의 요청 처리 메서드 (handleStep1, handleStep3 등 @Mapping이 붙은 메서드들)들이 실행되기 전 매번 실행되어 initBinder 메서드를 호출해 WebDataBinder를 초기화 한다.
글로벌 범위, 컨트롤러 범위 Validator의 우선 순위
만약 어떤 컨트롤러가 글로벌 범위와 컨트롤러 범위 두 개의 Validator가 검사하도록 되어 있고, WebDataBinder#setValidator()로 컨트롤러 범위 Validator를 지정했다면, 컨트롤러 범위 Validator로 검사하게 된다.
WebDataBinder는 내부적으로 Validator 목록을 갖고 있고 여기에는 글로벌 Validator도 포함되는데, WebDataBinder#setValidator()로 Validator를 추가할때 기존에 있던 Validator를 삭제하고 추가하기 때문이다.
출처 : 스프링5 프로그래밍 입문 (최범균 저)
'Web' 카테고리의 다른 글
Ch13. MVC 3 : 로그인 구현 (0) | 2022.07.23 |
---|---|
Ch12. MVC 2 : Bean Validation을 이용한 검증 (0) | 2022.07.22 |
Ch12. MVC 2 : 커맨드 객체의 값 검증과 에러 메시지 처리 (0) | 2022.07.19 |
Ch12. MVC 2 : 메시지 (0) | 2022.07.19 |
Ch11. MVC 1 : ModelAndView (0) | 2022.07.18 |
- Total
- Today
- Yesterday
- permutation
- Python
- 자료구조
- two pointer
- 조합
- Spring
- Implementation
- dfs
- Kruskal
- binary search
- Dijkstra
- 재귀
- priority queue
- back tracking
- Tree
- 이분탐색
- DP
- db
- BFS
- MVC
- graph
- C
- recursion
- floyd warshall
- Brute Force
- CSS
- Unity
- C++
- greedy
- Stack
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |