2016-09-30 73 views
1

我有這個任務來處理輸入.csv,.txt文件並將數據存儲到數據庫中。我正在使用Spring Batch來達到這個目的。在將數據轉儲到數據庫之前,我必須對數據執行一些驗證檢查。我使用Spring Batch的ValidatingItemProcessor和Hibernate的JSR-303參考實現hibernate驗證器爲相同。代碼看起來是這樣的:獲取驗證失敗的對象Spring批量驗證

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: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感謝您的評論。如何在ItemProcessor中將異常過濾爲SkipException?也正如你所看到的,我從我的驗證器而不是處理器產生異常。我應該改變這種行爲嗎? – raghav

回答

2

我猜你validatingPersonItemProcessor豆有他驗證參數設置與myBeanValidator。所以Exception將由處理器拋出。

創建您自己的SkipListener。在這裏,您將關於在物品未驗證時發生的情況(寫入文件,數據庫等)的邏輯放在onSkipInProcess();中。

您需要添加ValidationException<batch:skippable-exception-classes>所以他們會被抓住拋出(並不會終止批處理),並在<batch:listeners>添加SkipListener,所以這將是當一個異常被拋出調用。

編輯:回答評論。 如果你的處理器是ValidatingItemProcessor並且你設置了驗證器,它應該自動調用驗證。但是,如果您通過擴展自己的ValidatingItemProcessor,則應明確呼叫super.process(yourItem);process() of ValidatingItemProcessor)驗證您的物品。

+0

感謝您的回答。我做了以上所有。但我從我的驗證器中拋出異常。那麼我是否需要從處理器顯式調用Validator的validate()方法?不應該自動調用它?目前我對如何獲得驗證權利感到困惑。 – raghav

+0

以編輯方式回答 – Asoub

+0

謝謝,它工作。只是最後一件事。我在塊內的可跳過部分配置中使用ValidationException。但錯誤的輸入仍然是鏈中的下一個處理器。我的過濾器設置爲false。不應該錯誤的輸入被我的大塊註冊的SkipListener跳過並捕獲。 – raghav