https://sundaland.tistory.com/367
[ ▶ Validation ]
Spring MVC에서 validation(검증)은 컨트롤러에서 데이터를 처리하기 전에 데이터의 정확성을 보장하는 데 중요한 역할을 한다. 기본적으로 Spring MVC는 Bean Validation(JSR-303/JSR-380)을 통합하여 사용하며, Hibernate Validator가 기본 제공자로 사용된다. Bean Validation이 클래스패스에 존재하는 경우, Spring은 자동으로 LocalValidatorFactoryBean을 글로벌 Validator로 등록하여 컨트롤러 메서드에서 @Valid와 @Validated 애노테이션을 사용할 수 있게 해준다.
[ ▷ 디폴트 Validation 설정 ]
Spring MVC에서 @Valid 또는 @Validated를 사용하면, 해당 메서드 아규먼트에 대해 자동으로 검증이 수행된다.
@PostMapping("/submitForm")
public String handleForm(@Valid @ModelAttribute MyForm form, BindingResult result) {
if (result.hasErrors()) {
// 검증 오류 처리
return "errorPage";
}
// 폼 처리
return "successPage";
}
- @Valid는 MyForm 객체에 대한 검증을 트리거하며, 컨트롤러가 요청을 처리하기 전에 데이터가 유효한지 확인한다.
- BindingResult는 검증 오류를 캡처하며, 오류가 있는 경우 이를 확인하여 처리할 수 있다.
Spring은 기본적으로 LocalValidatorFactoryBean을 글로벌 Validator로 사용하여 검증 작업을 수행한다.
[ ▷ Java Configuration에서 글로벌 Validator 커스터마이징 ]
애플리케이션에 맞게 글로벌 Validator 인스턴스를 커스터마이징해야 할 경우가 있다. 예를 들어, 커스텀 검증 제공자를 설정하거나, 기본 Validator에 추가 기능을 확장하고자 할 수 있다.
글로벌 Validator를 커스터마이징하려면, WebMvcConfigurer 인터페이스의 getValidator() 메서드를 오버라이드한다.
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
@Override
public Validator getValidator() {
LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
// Validator에 대한 커스텀 설정을 추가할 수 있습니다.
return validator;
}
}
- LocalValidatorFactoryBean을 사용해 새로운 Validator 인스턴스를 생성한다.
- 이 Validator 인스턴스에 원하는 대로 커스텀 동작을 추가할 수 있다. 예를 들어, 메시지 인터폴레이터나 검증 팩토리를 설정할 수 있다.
[ ▷ 컨트롤러에서 로컬 Validator 구현 등록 ]
글로벌 Validator 외에도 특정 컨트롤러에서만 검증 논리를 적용하고 싶을 때 로컬 Validator를 등록할 수 있다. 이를 위해 WebDataBinder를 사용하여 개별 컨트롤러 수준에서 검증기를 설정할 수 있다.
▼ 컨트롤러에 로컬 Validator를 등록하는 방법
@Controller
public class MyController {
@InitBinder
protected void initBinder(WebDataBinder binder) {
binder.addValidators(new FooValidator());
}
}
- @InitBinder는 특정 컨트롤러 메서드에 대한 데이터 바인딩 과정을 커스터마이징할 때 사용된다.
- WebDataBinder는 FooValidator와 같은 로컬 검증기를 추가하여, 이 컨트롤러의 메서드에서만 적용되도록 할 수 있다.
[ ▷ LocalValidatorFactoryBean과 @Primary 사용 ]
애플리케이션의 다른 곳에서 LocalValidatorFactoryBean을 주입할 필요가 있는 경우(서비스 클래스에서), 해당 빈을 정의하고 @Primary로 마킹해야 한다. 이렇게 하면 MVC 설정에서 자동으로 선언된 Validator와 충돌을 피할 수 있다.
▼ @Primary로 LocalValidatorFactoryBean을 정의하는 예시
@Configuration
public class AppConfig {
@Bean
@Primary
public LocalValidatorFactoryBean validator() {
return new LocalValidatorFactoryBean();
}
}
- @Primary: 이 애노테이션은 여러 Validator 빈이 정의되어 있을 때, 이 validator() 빈이 기본적으로 사용되도록 보장한다. 이를 통해 Spring MVC에서 자동으로 등록되는 글로벌 Validator와 커스텀 Validator 간의 충돌을 방지할 수 있다.
[ ▷ Reactive 스택(Spring WebFlux)에서의 Validation ]
Spring WebFlux(reactive 스택)에서도 검증은 Spring MVC와 유사하게 작동한다. @Valid와 @Validated 애노테이션을 사용하여 컨트롤러 메서드 아규먼트에 대한 검증을 수행할 수 있으며, 비동기식 논블로킹 환경에 맞춰 실행다.
▼ reactive WebFlux 컨트롤러에서 검증을 수행하는 예시
@PostMapping("/submitForm")
public Mono<ResponseEntity<String>> handleForm(@Valid @RequestBody MyForm form, Errors errors) {
if (errors.hasErrors()) {
return Mono.just(ResponseEntity.badRequest().body("Validation error"));
}
// 폼 처리
return Mono.just(ResponseEntity.ok("Success"));
}
- @Valid는 MyForm 객체에 대한 검증을 트리거한다.
- Errors는 검증 오류를 캡처한다.
- reactive 타입은 비동기식 프로그래밍에 맞춰 Mono<ResponseEntity>로 설정된다.
[ ▷ WebFlux에서의 글로벌 Validator ]
WebFlux에서도 글로벌 Validator를 커스터마이징할 수 있으며, 이는 Spring MVC와 매우 유사하다. WebFluxConfigurer 인터페이스를 구현하고 getValidator() 메서드를 오버라이드하여 글로벌 Validator를 설정할 수 있다.
@Configuration
@EnableWebFlux
public class WebFluxConfig implements WebFluxConfigurer {
@Override
public Validator getValidator() {
LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
return validator;
}
}
이 방식은 MVC 설정과 동일하지만, 논블로킹 비동기 환경에서 작동한다.
[ ▷ WebFlux에서의 로컬 Validator ]
Spring MVC와 마찬가지로, WebFlux에서도 컨트롤러 수준에서 로컬 검증기를 등록할 수 있다. @InitBinder 애노테이션을 사용해 로컬 검증 로직을 특정 컨트롤러 메서드에만 적용할 수 있다.
@RestController
public class MyController {
@InitBinder
protected void initBinder(WebDataBinder binder) {
binder.addValidators(new FooValidator());
}
}
이 @InitBinder 애노테이션을 통해 WebFlux에서도 커스텀 검증 논리를 적용할 수 있다.
[ ▷ 요약 ]
- 글로벌 검증: Spring MVC에서는 Bean Validation(JSR-303/JSR-380)이 클래스패스에 있는 경우 자동으로 LocalValidatorFactoryBean이 글로벌 Validator로 등록된다.
- 글로벌 Validator 커스터마이징: WebMvcConfigurer 또는 WebFluxConfigurer의 getValidator() 메서드를 오버라이드하여 글로벌 Validator를 커스터마이징할 수 있다.
- 로컬 Validator: WebDataBinder와 @InitBinder를 사용하여 컨트롤러 내에서 로컬 검증기를 등록할 수 있다.
- WebFlux: reactive 스택(Spring WebFlux)에서도 유사한 검증 지원이 제공되며, @Valid 및 @Validated 애노테이션을 사용해 로컬 및 글로벌 검증기를 설정할 수 있다.
Spring MVC와 WebFlux에서 검증을 설정하고 커스터마이징함으로써, 동기식 및 비동기식 환경에서 애플리케이션 데이터의 정확성을 보장할 수 있다.
'Web on Servlet Stack' 카테고리의 다른 글
View Controllers (0) | 2024.10.15 |
---|---|
Content Types (1) | 2024.10.15 |
Type Conversion (0) | 2024.10.15 |
Interceptors (0) | 2024.10.15 |
MVC Config API (0) | 2024.10.15 |