[스프링 3.0] @Valid 실습

1. 라이브러리 추가.

        <!– Validation –>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>com.springsource.org.hibernate.validator</artifactId>
            <version>4.0.0.GA</version>
        </dependency>
        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>com.springsource.javax.xml.bind</artifactId>
            <version>2.1.7</version>
        </dependency>

2. 빈 설정.

    <bean
        class=”org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter”>
        <property name=”cacheSeconds” value=”0″ />
        <property name=”webBindingInitializer”>
            <bean class=”org.springframework.web.bind.support.ConfigurableWebBindingInitializer”>
                   <property name=”validator” ref=”validator” />
               </bean>
        </property>
    </bean>
   
    <bean id=”validator” class=”org.springframework.validation.beanvalidation.LocalValidatorFactoryBean”/>

3. 애노테이션 기반 검증 설정

    @Column(length = 100)
    @NotEmpty(message=”제목을 입력하세요!”)
    private String title;
    @Column(columnDefinition=”TEXT”)
    @NotEmpty(message=”제목을 입력하세요!”)
    private String contents;

4. 컨트롤러 코드 수정.

    @RequestMapping(value = “/notice/update/{id}”, method = RequestMethod.POST)
    public String updateForm(@Valid Notice notice, BindingResult result, SessionStatus status) {
        if (result.hasErrors()) {
            return “notice/update”;
        } else {
            noticeService.update(notice);
            status.setComplete();
            return “redirect:/notice/” + notice.getId() + “.do”;
        }
    }

끝~!! 기본 에러 메시지는 애노테이션에서 변경할 수 있습니다.

이제 JSR 303 애노테이션과 그 확장 애노테이션에 뭣들이 있는지 살펴봐야겠네요.

[스프링 3.0] @Valid 이론

http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/ch05s07.html#validation.mvc

스프링 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” />
               
이런 방법이 있군요.

그럼? 스프링이 검증 해준 다음은 어떻게 되는걸까요?? 검증 에러는 어떻게 받아오나? 검증 에러가 있으면 알아서 이전 폼을 다시 보여주나? 핸들러에서는 그럼 서브밋 됐을 때의 로직만 구현하는 되는건가? 실험해봐야겠군요.