获取验证失败的对象Spring Batch validation

时间:2016-09-30 04:10:35

标签: spring validation spring-batch bean-validation

我正在执行此任务来处理输入.csv,.txt文件并将数据存储到数据库中。我正在使用Spring Batch来达到这个目的。在将数据转储到数据库之前,我必须对数据执行一些验证检查。我正在使用Spring Batch的ValidatingItemProcessor和Hibernate的JSR-303参考实现hibernate验证器。代码看起来像:

public class Person{

@Pattern(regexp = "someregex")
String name;
@NotNull
String address;
@NotNull
String age;

//getters and setters

}

然后我写了一个看起来像这样的验证器 -

import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.ValidatorFactory;

import org.springframework.batch.item.validator.ValidationException;
import org.springframework.beans.factory.InitializingBean;

import org.springframework.batch.item.validator.Validator;

 class MyBeanValidator implements Validator<Person>, InitializingBean{

   private javax.validation.Validator validator;

        @Override
        public void afterPropertiesSet() throws Exception {
            ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory();
            validator = validatorFactory.usingContext().getValidator();
        }

        @Override
        public void validate(Person person) throws ValidationException {
            Set<ConstraintViolation<Object>> constraintViolations =  validator.validate(person);

            if(constraintViolations.size() > 0) {
                generateValidationException(constraintViolations);
            }

        }
private void generateValidationException(Set<ConstraintViolation<Object>>   constraintViolations) {
            StringBuilder message = new StringBuilder();

            for (ConstraintViolation<Object> constraintViolation : constraintViolations) {
                message.append(constraintViolation.getMessage() + "\n");
            }

            throw new ValidationException(message.toString());
}

然后我有一个处理器,它继承了Spring Batch的ValidatingItemProcessor

 public class ValidatingPersonItemProcessor extends    ValidatingItemProcessor<Person>{


@Override
public Person process(Person person) {

//some code
 }

通过验证检查的记录将被传递到另一个处理器进行进一步处理,但失败的记录将被清除,然后传递给下一个处理器。

  1. 现在我想抓住验证失败的记录。我的目标是报告所有未通过验证的输入记录,并在将这些记录传递给下一个处理器进行进一步处理之前进一步清理这些记录。我怎样才能做到这一点?

  2. 如果某些输入的验证失败,Spring Batch进程会终止吗?如果是,如何避免?我的处理器配置类似于:

    <batch:chunk reader="personItemReader" writer="personDBWriter"  processor="personProcessor"
                commit-interval="100" skip-limit="100">
                <batch:skippable-exception-classes>
                    <batch:include   class="org.springframework.batch.item.validator.ValidationException"/>
                </batch:skippable-exception-classes>
                <batch:listeners>
                    <batch:listener>
                        <bean
                               class="org.someorg.poc.batch.listener.PersonSkipListener" />
                    </batch:listener>
                </batch:listeners>
            </batch:chunk>
    <bean id="personProcessor"
    class="org.springframework.batch.item.support.CompositeItemProcessor">
      <property name="delegates">
        <list>
          <ref bean="validatingPersonItemProcessor" />
          <ref bean="personVerifierProcessor" />
       </list>
      </property>
    </bean>
       <bean id="validatingPersonItemProcessor" class="org.someorg.poc.batch.processor.ValidatingPersonItemProcessor" scope="step">
       <property name="validator" ref="myBeanValidator" />
       </bean>
    
         <bean id="myBeanValidator" class="org.someorg.poc.batch.validator.MyBeanValidator">
    </bean>
    
        <bean id="personVerifierProcessor" class="org.someorg.poc.batch.processor.PersonVerifierProcessor"     scope="step"/>
       </beans>
    

1 个答案:

答案 0 :(得分:2)

我猜你的validatingPersonItemProcessor bean的验证器参数设置为myBeanValidator。所以处理器会抛出Exception

创建自己的SkipListener。在这里,您将逻辑放在onSkipInProcess();上未验证项目(写入文件,数据库等)时发生的事情。

您需要添加ValidationException投放到<batch:skippable-exception-classes>以便它们被捕获(并且不会终止您的批处理),并在<batch:listeners>中添加您的SkipListener,所以当抛出异常时它会被调用。

编辑:回答评论。 如果您的处理器是ValidatingItemProcessor 并且您设置了验证器,它应该自动调用validate。但是,如果您通过扩展自己制作自己的ValidatingItemProcessor,则应明确地致电super.process(yourItem);process() of ValidatingItemProcessor )以验证您的商品。