2014-04-25 28 views
3

在Spring Batch項目中,我需要編寫多行記錄。我正在執行ItemReader以在返回對象之前累計多行。在完成幾個示例項目之後,我將它們拼湊在一起,但我面臨着一個ReaderNotOpenException在Spring Batch項目中實現ItemReader時,如何打開Reader?

我已經三重檢查了文件的路徑是否正確。當我調試delegate包含我的配置文件中的資源和文件路徑。

任何幫助表示讚賞。

配置文件:

<bean id="cvsFileItemReader" class="com.mkyong.XYZFileRecordReader"> 
    <property name="delegate"> 
     <bean class="org.springframework.batch.item.file.FlatFileItemReader"> 
      <property name="resource" value="classpath:ma/report-headeronly.psv" /> 
      <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="delimiter" value="|" /> 
         </bean> 
        </property> 
        <property name="fieldSetMapper"> 
         <bean class="org.springframework.batch.item.file.mapping.PassThroughFieldSetMapper" /> 
        </property> 
       </bean> 
      </property> 
     </bean> 
    </property> 
</bean> 

我的讀者:

package com.mkyong; 

import org.springframework.batch.item.ExecutionContext; 
import org.springframework.batch.item.ItemReader; 
import org.springframework.batch.item.ItemStream; 
import org.springframework.batch.item.ItemStreamException; 
import org.springframework.batch.item.NonTransientResourceException; 
import org.springframework.batch.item.ParseException; 
import org.springframework.batch.item.UnexpectedInputException; 
import org.springframework.batch.item.file.FlatFileItemReader; 
import org.springframework.batch.item.file.transform.FieldSet; 

import com.mkyong.model.XYZFileHeaderRecord; 

public class XYZFileRecordReader implements ItemReader<XYZFileHeaderRecord>, ItemStream { 

private FlatFileItemReader<FieldSet> delegate; 

@Override 
public XYZFileHeaderRecord read() throws Exception, 
     UnexpectedInputException, ParseException, 
     NonTransientResourceException { 

    XYZFileHeaderRecord maFileHeaderRecord = new XYZFileHeaderRecord(); 

    for (FieldSet line = null; (line = this.delegate.read()) != null;) { 
     String firstToken = line.readString(0); 
     if (firstToken.equals("File ID")) { 
      maFileHeaderRecord.setFileName(line.readString(1)); 
     } else if (firstToken.equals("Date")) { 
      maFileHeaderRecord.setDate(line.readString(1)); 
      return maFileHeaderRecord; 
     } 
    } 

    return null; 
} 

@Override 
public void close() throws ItemStreamException {} 

@Override 
public void open(ExecutionContext arg0) throws ItemStreamException {} 

@Override 
public void update(ExecutionContext arg0) throws ItemStreamException {} 

public FlatFileItemReader<FieldSet> getDelegate() { 
    return delegate; 
} 

public void setDelegate(FlatFileItemReader<FieldSet> delegate) { 
    this.delegate = delegate; 
} 
} 

我的堆棧跟蹤:

SEVERE: Encountered an error executing the step 
org.springframework.batch.item.ReaderNotOpenException: Reader must be open before it can be read. 
    at org.springframework.batch.item.file.FlatFileItemReader.readLine(FlatFileItemReader.java:195) 
    at org.springframework.batch.item.file.FlatFileItemReader.doRead(FlatFileItemReader.java:173) 
    at org.springframework.batch.item.support.AbstractItemCountingItemStreamItemReader.read(AbstractItemCountingItemStreamItemReader.java:83) 
    at com.mkyong.XYZFileRecordReader.read(XYZFileRecordReader.java:26) 
    at com.mkyong.XYZFileRecordReader.read(XYZFileRecordReader.java:1) 
    at org.springframework.batch.core.step.item.SimpleChunkProvider.doRead(SimpleChunkProvider.java:91) 
    at org.springframework.batch.core.step.item.SimpleChunkProvider.read(SimpleChunkProvider.java:155) 
    at org.springframework.batch.core.step.item.SimpleChunkProvider$1.doInIteration(SimpleChunkProvider.java:114) 
    at org.springframework.batch.repeat.support.RepeatTemplate.getNextResult(RepeatTemplate.java:368) 
    at org.springframework.batch.repeat.support.RepeatTemplate.executeInternal(RepeatTemplate.java:215) 
    at org.springframework.batch.repeat.support.RepeatTemplate.iterate(RepeatTemplate.java:144) 
    at org.springframework.batch.core.step.item.SimpleChunkProvider.provide(SimpleChunkProvider.java:108) 
    at org.springframework.batch.core.step.item.ChunkOrientedTasklet.execute(ChunkOrientedTasklet.java:69) 
    at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:395) 
    at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:131) 
    at org.springframework.batch.core.step.tasklet.TaskletStep$2.doInChunkContext(TaskletStep.java:267) 
    at org.springframework.batch.core.scope.context.StepContextRepeatCallback.doInIteration(StepContextRepeatCallback.java:77) 
    at org.springframework.batch.repeat.support.RepeatTemplate.getNextResult(RepeatTemplate.java:368) 
    at org.springframework.batch.repeat.support.RepeatTemplate.executeInternal(RepeatTemplate.java:215) 
    at org.springframework.batch.repeat.support.RepeatTemplate.iterate(RepeatTemplate.java:144) 
    at org.springframework.batch.core.step.tasklet.TaskletStep.doExecute(TaskletStep.java:253) 
    at org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:195) 
    at org.springframework.batch.core.job.SimpleStepHandler.handleStep(SimpleStepHandler.java:137) 
    at org.springframework.batch.core.job.flow.JobFlowExecutor.executeStep(JobFlowExecutor.java:64) 
    at org.springframework.batch.core.job.flow.support.state.StepState.handle(StepState.java:60) 
    at org.springframework.batch.core.job.flow.support.SimpleFlow.resume(SimpleFlow.java:152) 
    at org.springframework.batch.core.job.flow.support.SimpleFlow.start(SimpleFlow.java:131) 
    at org.springframework.batch.core.job.flow.FlowJob.doExecute(FlowJob.java:135) 
    at org.springframework.batch.core.job.AbstractJob.execute(AbstractJob.java:301) 
    at org.springframework.batch.core.launch.support.SimpleJobLauncher$1.run(SimpleJobLauncher.java:134) 
    at org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:49) 
    at org.springframework.batch.core.launch.support.SimpleJobLauncher.run(SimpleJobLauncher.java:127) 
    at com.mkyong.App.main(App.java:27) 
Apr 25, 2014 5:35:56 PM org.springframework.batch.core.launch.support.SimpleJobLauncher$1 run 
INFO: Job: [FlowJob: [name=reportJob]] completed with the following parameters: [{}] and the following status: [FAILED] 
Exit Status : FAILED 
Done 

回答

11

您的委託是沒有得到開放。解決此問題的最簡單方法是更新open,closeupdate方法,以便在代理上調用相應的方法。這也使得重啓(其當前版本不會因爲代理的狀態沒有被保存):

@Override 
public void close() throws ItemStreamException { 
    delegate.close(); 
} 

@Override 
public void open(ExecutionContext arg0) throws ItemStreamException { 
    delegate.open(arg0); 
} 

@Override 
public void update(ExecutionContext arg0) throws ItemStreamException { 
    delegate.update(arg0); 
} 

另一種方法是註冊FlatFileItemReader在你的腳步流。如果你想要走這條路線,你必須將它拉出到一個單獨的bean定義中。

你可以閱讀更多關於ItemStream S和如何在其生命週期的作品以及它是如何通過委託在這裏的影響:http://docs.spring.io/spring-batch/reference/html-single/index.html#itemStream

1

你必須調用delegate.open()來執行開放真正的讀者的。或者您可以註冊代理閱讀器作爲流,讓SB管理代理閱讀器流生命週期(閱讀chapter 6.5

相關問題