Common Validation Framework - How To Validate a Java Bean

8849 단어
Common Validation Framework - How To Validate a Java Bean
Recently, more and more java developers show the great interesting on validation of java objects. This article (The importance of Being Valid) describes the importance of being valid. Several years ago, there maybe only presentation-layer validation, such as Struts Validation Framework. After that, Apache abstracts Apache Common Validation Framework from struts validation. Unfortunately, this common validation is still tightly connected to presentation-layer.
Now, lots of new framework is coming. The following is the uncompleted list of java validation framework
  • Presentation Validation Framework – such as Struts validation, Tapestry
  • Apache Common Validation
  • iScreen: iScreen is a Java object validation framework (that is, it validates POJOs). http://www.i-screen.org/docs/FAQ.html
  • Hibernate Validation: Hibernate Validator integrates with Hibernate by applying the constraints on the database schema (DDL generation) and by checking entity validity before Hibernate inserts or updates instances. http://www.hibernate.org/412.html.
  • Spring Validation – which is part of the Spring Modules project, allows you to perform validation declaratively using Java annotations.

  • And JSR 303 (Bean Validation) try to come out a set of standards of bean validation and now is on Early Draft Review stage. However, i didn’t find any implementation already supporting this spec.
    After some investigation, i selected Spring Bean Validation Module. The major reasons are
  • Bean Validation Support: As a common service, what we need is a common bean validation which provides more features, more flexibility, more power, and fewer dependencies on libraries or frameworks.
  • It should support XML configuration based validation and Annotation based validation
  • easy to integrate with Spring.
  • Pure Java Technology

  • Unfortunately, there are very few examples to show how to use Spring framework without Spring MVC framework. This one is the only reference – Annotation-Based Validation with the Spring Bean Validation Framework.
    This article describes how to use Spring Bean Framework in your code.
  • Required Jars spring-modules-validation.jar from spring-modules-0.9
  • Java Bean: The following is a bean to be validated
    public class AuthenticateUserInput extends Input {
    @NotNull(errorCode = UserAccountErrorCodeAndMessage.AUTHENTICATE_USER_INPUT_ACCOUNT_NAME_IS_NULL,
    @NotBlank(errorCode = UserAccountErrorCodeAndMessage.AUTHENTICATE_USER_INPUT_ACCOUNT_NAME_IS_EMPTY,message="account name cannot be blank")
    private String accountName;
    @NotNull(errorCode = UserAccountErrorCodeAndMessage.AUTHENTICATE_USER_INPUT_ACCOUNT_NAME_IS_NULL,message="user name cannot be null")
    @NotBlank(errorCode = UserAccountErrorCodeAndMessage.AUTHENTICATE_USER_INPUT_ACCOUNT_NAME_IS_EMPTY,message="user name cannot be blank")
    private String userName;
    @NotNull(errorCode = UserAccountErrorCodeAndMessage.AUTHENTICATE_USER_INPUT_PASSWORD_IS_NULL,message="password cannot be null")
    @NotBlank(errorCode = UserAccountErrorCodeAndMessage.AUTHENTICATE_USER_INPUT_PASSWORD_IS_EMPTY,message="password cannot be blank")
    private String password;
    // getter and setter for attributes
    }
    In the above example, each attribute has two annotation based validation rules - (1) NotNull: its error code is a user-defined string, and the message will be returned if specified (2) NotBlank: its error code is a user-defined string, and the message will be returned if specified
  • Configurations Main Spring Configuration file (webapps"useraccount"WEB-INF"appContext.xml) is required to configure Validator Bean and ValidationConfigurationLoader.
    <beans default-autowire="byName" xsi:schemalocation=" 
    <a href="http://www.springframework.org/schema/beans">http://www.springframework.org/schema/beans</a>
    <a href="http://www.springframework.org/schema/beans/spring-beans.xsd">http://www.springframework.org/schema/beans/spring-beans.xsd</a>
    <a href="http://www.springmodules.org/validation/bean/validator">http://www.springmodules.org/validation/bean/validator</a>
    <a href="http://www.springmodules.org/validation/bean/validator.xsd">http://www.springmodules.org/validation/bean/validator.xsd</a>"
    xmlns:vld="http://www.springmodules.org/validation/bean/validator"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans">
    &lt;!--Bean Validator-->
    <vld:annotation-based-validator id="beanValidator">
    &lt;!--vld:xml-based-validator id="validator">
    <vld:resource location="classpath:validation.xml"/>
    </vld:xml-based-validator-->
    &lt;!--bean id="configurationLoader" class="org.springmodules.validation.bean.conf.loader.xml.DefaultXmlBeanValidationConfigurationLoader">
    <property name="resource" value="classpath:validation.xml"/>
    </bean>
    <bean id="beanValidator" class="org.springmodules.validation.bean.BeanValidator">
    <property name="configurationLoader">
    <ref bean="configurationLoader"/>
    </property>
    </bean-->

    </vld:annotation-based-validator></beans>
  • NOTE: we are using annotation based validation rule, if you want to use XML configuration based rule, you can uncomment vld:xml-based-validator section.
  • Inject Validator to your code and validate the bean Ok, now we already get a user-defined validator, whose name is beanValidator.NOTE: it is defined by annotation-based-validator. So, the validation framework will load validation rules from annotation. Now, Let’s see how to use it. According to Spring Dependency Injection principle, we need define a bean to inject this validator.
    public
     
    class
     CommonValidator {
    private
     
    static
     CommonValidator instance 
    =
     createInstance();
    private
     Validator validator;
    /**
     * This is a singleton class. 
    */
    private
     CommonValidator() { }
    private
     
    static
     CommonValidator createInstance() {
    return
     
    new
     CommonValidator(); }
    public
     
    static
     CommonValidator getInstance() {
    return
     instance; }
    /**
     * 
    @return
     the validator 
    */
    public
     Validator getValidator() {
    return
     validator; }
    /**
     * 
    @param
     validator the validator to set 
    */
    public
     
    void
     setValidator(Validator validator) {  
    this
    .validator 
    =
     validator;  } 
    public
     
    boolean
     validate(Input input, Output output) { Errors errors 
    =
     
    new
     BindException(input, 
    ""
    ); validator.validate(input, errors); 
    if
     (errors.hasErrors()) {
    for
     (Object o : errors.getAllErrors()) {  FieldError e 
    =
     (FieldError)o; String errorCode 
    =
     e.getCode();  errorCode 
    =
     errorCode.substring(errorCode.indexOf(
    '
    [
    '

    +
     
    1
    , errorCode.indexOf(
    '
    ]
    '
    ));  output.addError(errorCode, e.getDefaultMessage());  } 
    return
     
    false
    ; } 
    return
     
    true
    ; } }
    So, the spring framework will inject user-defined validator instance into this class with initialization time. And boolean validate(Input, Output) is the only method to validate a input. If any validation rule is violated, the output class get add a error. The last step will show the configuration to inject user-defined validator. It is also in AppContext.xml.
        <bean class="com.starcite.user.validator.CommonValidator" id="commonValidator" factory-method="getInstance">
    <property name="validator">
    <ref bean="beanValidator">
    </ref></property>
    </bean>

  • Have Fun!

    좋은 웹페이지 즐겨찾기