[스프링 3.0] @Valid 이론
스프링 3.0에서 검증(validation) 설정에 대한 자바 표준인 JSR-303을 지원하기 시작했습니다.
public class Person {
@NotNull
@Max(64)
private String name;
@Min(0)
private int age;
}
이런식으로 도메인 모델에 검증 메타데이터를 정의할 수 있는거죠. 이렇게 정의해둔 정보들은 JSR-303 Validator가 검증할 때 활용합니다. 이 검증기는 하이버네이트가 구현한것도 있고, 스프링 3.0에서 제공하는 것도 있습니다.
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />
스프링에서 제공하는 검증기는 위에 있는 클래스입니다 이 클래스는 javax.validation.Validator 인터페이스와 org.springframework.validation.Validator 인터페이스를 구현했기 때문에 필요한 곳에서 적당한 인터페이스 타입으로 참조해서 사용하면 됩니다.
이밖에도 커스텀 @Constraint 만드는 방법과 DataBinder에서 스프링 검증기 사용하는 방법이 나와있으나 그 부분은 생략하겠습니다. 저는 지금 스프링 3.0 MVC에 적용하는 방법을 익히려고 정리중입니다.
이전까지는 @Controller 기반 컨트롤러를 사용할 때는 Validation 과정을 일일히 손수 코딩해줘야했습니다. 그러나 이제는 스프링이 자동으로 검증로직을 호출도록 설정할 수 있습니다. 그 방법이 바로 이 글의 제목인 @Valid죠.
@Controller
public class MyController {
@RequestMapping("/foo", method=RequestMethod.POST)
public void processFoo(@Valid Foo foo) { ... }
}
스프링 바인딩이 끝나면, 해당 객체에 설정된 Validator를 호출해 줍니다. 이때 호출해야 할 Validator를 설정하는 방법은 두 가지가 있습니다. 하나는 @Controller의 @InitBinder 마다 설정하는 방법이고, 다른 하나는 글로벌한 InitBinder라고 볼 수 있는 WebBindingInitializer에 설정하는 방법입니다.
@Controller
public class MyController {
@InitBinder
protected void initBinder(WebDataBinder binder) {
binder.setValidator(new FooValidator());
}
@RequestMapping("/foo", method=RequestMethod.POST)
public void processFoo(@Valid Foo foo) { ... }
}
이 방법과~
<!-- Invokes Spring MVC @Controller methods -->
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="webBindingInitializer">
<!-- Configures Spring MVC DataBinder instances -->
<bean class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer">
<property name="validator" ref="validator" />
</bean>
</property>
</bean>
<!-- Creates the JSR-303 Validator -->
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />
이런 방법이 있군요.
그럼? 스프링이 검증 해준 다음은 어떻게 되는걸까요?? 검증 에러는 어떻게 받아오나? 검증 에러가 있으면 알아서 이전 폼을 다시 보여주나? 핸들러에서는 그럼 서브밋 됐을 때의 로직만 구현하는 되는건가? 실험해봐야겠군요.