2014-01-31 6 views
4

springbatch + quartz 설정에서 FlatFileItemReader를 사용하여 CSV 파일을 읽습니다. 리더에 대한 커서를 설정하여 독자에게 주어진 매개 변수를 사용하여 다음 작업 인스턴스를 시작하려고합니다. 가능한가?스프링 배치 ItemReader FlatFileItemReader는 커서를 설정하여 특정 라인에서 읽기를 시작하거나 linestoskip을 동적으로 설정합니다.

<bean id="cvsFileItemReader" class="org.springframework.batch.item.file.FlatFileItemReader" scope="step"> 
    <!-- Read a csv file --> 
    <property name="resource" value="classpath:cvs/input/report.csv" /> 

    <property name="lineMapper"> 
     <bean class="org.springframework.batch.item.file.mapping.DefaultLineMapper"> 
      <property name="lineTokenizer"> 
       <bean 
        class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer"> 
        <property name="names" value="id,impressions" /> 
       </bean> 
      </property> 
      <property name="fieldSetMapper"> 
       <bean 
        class="org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper"> 
        <property name="prototypeBeanName" value="report" /> 
       </bean> 
      </property> 
     </bean> 
    </property> 

</bean> 

아이디어는 다음 번 실행시 마지막 실패가 발생한 파일을 계속 읽는 것입니다. 내 customWriter 작성된 각 줄에 대한 정수 'writecursor'퍼팅입니다.

public void write(List<? extends Report> items) throws Exception { 

System.out.println("writer..." + items.size() + " > ");  
for(Report item : items){ 
    System.out.println("writing item id: " + item.getId());  
    System.out.println(item); 

} 
//getting stepExecution by implementing StepExecutionListener 
this.stepExecution.getExecutionContext().putInt("writecursor", ++writecursor); 

} 

는 이제 customItemReadListener에, 나는 업데이트 writecursor 값을 가져온 다음 writecursor 내가 가능한 솔루션으로 본 또 다른 한가지는

public class CustomItemReaderListener implements ItemReadListener<Report>, StepExecutionListener { 

    ApplicationContext context = ApplicationContextUtils.getApplicationContext(); 
    private StepExecution stepExecution; 
    @Override 
    public void beforeRead() { 
     //Skip lines somehow 
    } 

에서 읽기 시작 상단에서 줄을 건너 뛰려면 itemreader에서 linestoskip을 동적으로 설정하는 방법. 여기에 스레드가 있습니다 http://thisisurl.com/dynamic-value-for-linestoskip-in-itemreader하지만 아직 답변하지 않았습니다. 그리고 여기, http://forum.spring.io/forum/spring-projects/batch/100950-accessing-job-execution-context-from-itemwriter

+1

가능한 중복 ([봄 일괄 작업 csv 파일이 실패 라인 복구 읽기] http://stackoverflow.com/questions/21451934/spring-batch-job-csv-file-read-recover-the-line-where-it-failed) –

+0

그래, 가능한 중복. 독자의 linestoskip 속성을 사용해 보았습니다. 하지만 지금은 stepexecution에서 커서 값을 저장하는 대신에 커서 값이 다음 jobexecution에서 재설정되므로 jobexecutioncontext에 저장해야한다고 생각합니다. ItemReader/Processor/Writer에서 jobexecutioncontext에 액세스하는 방법은 무엇입니까? – Saad

+0

내 대답을 확인하십시오. 하지만 IMHO는 SB 내장 기능 만 복제하고 있습니다. –

답변

4

속성 설정 주입 작업 매개 변수 값을 사용하십시오. 이동하는 라인을 구현

<bean id="myReader" class="org.springframework.batch.item.file.FlatFileItemReader" scope="step"> 
    <property name="linesToSkip" value="file:#{jobParameters['cursor']}" /> 
</bean> 
+0

저에게 잘 작동합니다. jobParamertes를 stepExecutionContext 또는 jobExecutionContext로 바꿀 수 있습니까? – Saad

+0

예. 대신 stepExecution 또는 jobExecution 데이터를 사용하도록 연결할 수 있습니다. –

1

보다 쉬운 방법입니다 다음

는 XML에서 리더 플랫 파일 리더 생성

아래와 같이 단계 실행 수신기의 beforeStep에 리더 autowire하기
public class CustomStepListener implements StepExecutionListener { 

    @Autowired 
    @Qualifier("cvsFileItemReader") 
    FlatFileItemReader cvsFileItmRdr; 

    @Override 
    public void beforeStep(StepExecution stepExecution) { 
     System.out.println("StepExecutionListener -------- beforeStep");    
     cvsFileItmRdr.setLinesToSkip(4); 
    } 

    @Override 
    public ExitStatus afterStep(StepExecution stepExecution) { 
     System.out.println("StepExecutionListener - afterStep"); 
     return null; 
    } 

} 

그것은 나를 위해 잘 작동 .....의