获取验证失败的对象 Spring 批量验证
Get the object which failed validation Spring Batch 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 批处理的 ValidatingItemProcessor
。
public class ValidatingPersonItemProcessor extends ValidatingItemProcessor<Person>{
@Override
public Person process(Person person) {
//some code
}
通过验证检查的记录将被传递到另一个处理器进行进一步处理,但失败的记录将被清理,然后传递到下一个处理器。
现在我想抓住验证失败的记录。我的 objective 是报告所有未通过验证的输入记录,并在我将这些记录传递给下一个处理器进行进一步处理之前进一步清理这些记录。我怎样才能做到这一点?
如果某些输入的验证失败,Spring 批处理是否会终止?如果是,如何避免?我的处理器配置类似于:
<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>
我猜你的 validatingPersonItemProcessor
bean 已经用你的 myBeanValidator
设置了他的验证器参数。所以 Exception
将被处理器抛出。
创建您自己的 SkipListener。在这里,您将逻辑放在 onSkipInProcess();
.
中当项目未验证(写入文件、数据库等)时会发生什么
您需要添加您在 <batch:skippable-exception-classes>
中抛出的 ValidationException
,这样它们就会被捕获(并且不会终止您的批处理),并在 <batch:listeners>
中添加您的 SkipListener,所以它会在抛出异常时被调用。
编辑:回复评论。
如果您的处理器是 ValidatingItemProcessor and you set the validator, it should automatically call validate. However if you make your own ValidatingItemProcessor
by extending it, you should explicitely call super.process(yourItem);
(process()
of ValidatingItemProcessor ) 来验证您的项目。
我的任务是处理输入的 .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 批处理的 ValidatingItemProcessor
。
public class ValidatingPersonItemProcessor extends ValidatingItemProcessor<Person>{
@Override
public Person process(Person person) {
//some code
}
通过验证检查的记录将被传递到另一个处理器进行进一步处理,但失败的记录将被清理,然后传递到下一个处理器。
现在我想抓住验证失败的记录。我的 objective 是报告所有未通过验证的输入记录,并在我将这些记录传递给下一个处理器进行进一步处理之前进一步清理这些记录。我怎样才能做到这一点?
如果某些输入的验证失败,Spring 批处理是否会终止?如果是,如何避免?我的处理器配置类似于:
<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>
我猜你的 validatingPersonItemProcessor
bean 已经用你的 myBeanValidator
设置了他的验证器参数。所以 Exception
将被处理器抛出。
创建您自己的 SkipListener。在这里,您将逻辑放在 onSkipInProcess();
.
您需要添加您在 <batch:skippable-exception-classes>
中抛出的 ValidationException
,这样它们就会被捕获(并且不会终止您的批处理),并在 <batch:listeners>
中添加您的 SkipListener,所以它会在抛出异常时被调用。
编辑:回复评论。
如果您的处理器是 ValidatingItemProcessor and you set the validator, it should automatically call validate. However if you make your own ValidatingItemProcessor
by extending it, you should explicitely call super.process(yourItem);
(process()
of ValidatingItemProcessor ) 来验证您的项目。