2016-09-30 3 views
1

У меня есть эта задача для обработки входных файлов .csv, .txt и хранения данных в базе данных. Для этой цели я использую Spring Batch. Перед тем, как сбрасывать данные в базу данных, я должен выполнить некоторые проверки проверки данных. Я использую Spring Batch's ValidatingItemProcessor и Hibernate's 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. Будет ли процесс весенней партии прекращаться, если проверка не выполняется для некоторого ввода? Если да, как этого избежать? Моя конфигурация процессора выглядит примерно так:

    <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> 
    
+0

Возможный дубликат [как создать отчет по отфильтрованным элементам в весенней партии?] (Http://stackoverflow.com/questions/12999435/how-to-create-a-report-on-filtered-items- in-spring-batch) –

+0

Также проверьте http://stackoverflow.com/questions/27318466/spring-batch-how-to-filter-duplicated-items-before-send-it-to-itemwriter –

+0

@LucaBassoRicci Спасибо за комментарий. Как фильтровать исключение как SkipException в ItemProcessor? Также, как вы можете видеть, я генерирую исключение из своего валидатора, а не процессора. Должен ли я изменить это поведение? – raghav

ответ

2

Я предполагаю, что ваш validatingPersonItemProcessor боб имеет свой параметр валидатор установить с myBeanValidator. Таким образом, процессор Exception будет выброшен.

Создайте свой собственный SkipListener. Здесь вы помещаете логику того, что происходит, когда элемент не проверяется (записывается в файл, DB и т. Д.), В onSkipInProcess();.

Вы должны добавить ValidationException вы бросаете в <batch:skippable-exception-classes> так что они будут пойманной (и не прекращает свой пакет), и добавить SkipListener в <batch:listeners>, так что это будет назвать, когда исключение.

EDIT: Ответить на комментарий. Если ваш процессор является ValidatingItemProcessor, и вы устанавливаете валидатор, он должен автоматически вызывать подтверждение. Однако, если вы сделаете свой собственный ValidatingItemProcessor, расширив его, вы должны прямо позвонить super.process(yourItem); (process() of ValidatingItemProcessor), чтобы подтвердить свой товар.

+0

Спасибо за ответ. Я сделал все вышеперечисленное.Но я выбрал исключение из своего валидатора. Так что мне нужно явно вызвать метод validate() моего Validator с процессора? Если он не будет автоматически вызываться самостоятельно? В настоящее время я смущен тем, как получить право на проверку. – raghav

+0

Ответил как edit – Asoub

+0

Спасибо, это сработало. Просто последнее. Я использую ValidationException в моей конфигурации с возможностью пропуска в куске. Но неисправный вход по-прежнему идет к следующему процессору в цепочке. Мой фильтр установлен в значение false. Не следует ли пропускать ошибочный вход и ловить мой SkipListener, который я зарегистрировал с помощью своего куска. – raghav

 Смежные вопросы

  • Нет связанных вопросов^_^