使用MultiResourceItemReader读取2个纯文本文件并写入单个文件

时间:2015-10-29 09:44:54

标签: spring-batch

我的批处理作业将生成2个文本文件,每行包含字符串格式。我创建了一个读者

<bean id="myMultiResourceReader"
    class=" org.springframework.batch.item.file.MultiResourceItemReader">
    <property name="resources" value="file:D:/MY/sample/*.txt" />
</bean> 
<bean id="myFinalWriter" class="org.springframework.batch.item.file.FlatFileItemWriter"
    scope="step">
    <property name="resource" value="${test.file3}" />
    <property name="lineAggregator">
        <bean
            class="org.springframework.batch.item.file.transform.PassThroughLineAggregator" />
    </property>
    <property name="footerCallback" ref="myFinalCustomItemWriter" />
    <property name="headerCallback" ref="myFinalCustomItemWriter" />
</bean>
<bean id="myFinalCustomItemWriter" class="my.process.MyWriter"
    scope="step">
    <property name="delegate" ref="myFinalWriter" />
    <property name="stepContext" value="#{stepExecution.stepName}" />
</bean>

我收到了这个错误:

Caused by: org.springframework.beans.ConversionNotSupportedException: Failed to convert property value of type 'com.sun.proxy.$Proxy68 implementing org.springframework.batch.item.file.ResourceAwareItemWriterItemStream,org.springframework.beans.factory.InitializingBean,org.springframework.batch.item.ItemStreamWriter,org.springframework.batch.item.ItemStream,org.springframework.aop.scope.ScopedObject,java.io.Serializable,org.springframework.aop.framework.AopInfrastructureBean,org.springframework.aop.SpringProxy,org.springframework.aop.framework.Advised' to required type 'org.springframework.batch.item.file.FlatFileItemWriter' for property 'delegate'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [com.sun.proxy.$Proxy68 implementing org.springframework.batch.item.file.ResourceAwareItemWriterItemStream,org.springframework.beans.factory.InitializingBean,org.springframework.batch.item.ItemStreamWriter,org.springframework.batch.item.ItemStream,org.springframework.aop.scope.ScopedObject,java.io.Serializable,org.springframework.aop.framework.AopInfrastructureBean,org.springframework.aop.SpringProxy,org.springframework.aop.framework.Advised] to required type [org.springframework.batch.item.file.FlatFileItemWriter] for property 'delegate': no matching editors or conversion strategy found

基本上我只想组合两个普通文件,并在页脚附加总计数。然后删除两个输入文件。可以帮忙吗?

MyWriter.java

public class MyWriter implements ItemWriter<String>, FlatFileFooterCallback, FlatFileHeaderCallback, ItemStream{
private static Logger log = Logger.getLogger(MyWriter.class);
private FlatFileItemWriter<String> delegate;
private int recordCount = 0;
private String stepContext;

public void writeFooter(Writer writer) throws IOException {
    writer.write("#" + recordCount);
}

public void writeHeader(Writer writer) throws IOException {
    writer.write("#" + StringUtil.getSysDate());
}

public void setDelegate(FlatFileItemWriter<String> delegate) {
    this.delegate = delegate;
}

public void write(List<? extends String> list) throws Exception {
     int chunkRecord = 0;
    for (String item : list) {
        chunkRecord++;
    }
    delegate.write(list);
    recordCount += chunkRecord;
}

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

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

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

public void setStepContext(String stepContext) {
    this.stepContext = stepContext;
}

}

2 个答案:

答案 0 :(得分:0)

正如Luca Basso Ricci已经指出的那样,问题是你在MyWriter中的委托定义。由于Spring为it bean创建代理,因此它不会将FlatFileItemReader识别为FlatFileItemWriter的实际实例,因此setDelegate(FlatFileItemWriter委托)将失败。

在MyWriter中使用ItemStreamWriter。正如您在异常消息中看到的,创建的代理确实提供了此接口。因此,它可以插入

这将解决委托写入,打开,关闭和更新方法的问题。为了编写页眉和页脚,您需要实现HeaderCallback和FooterCallback并将其直接设置在FlatFileItemWriter的定义中。

实现HeaderCallback不是问题,因为您只设置了systemdate。

作为FooterCallback,制作自己的Bean。在FlatFileItemWriter中使用它来编写页脚。添加“increaseCount”方法并在MyWriter Bean中使用它来增加写入次数。

public void write(List<? extends String> list) throws Exception {
    myFooterCallback.increaseCount(list.size());
    delegate.write(list);
}

答案 1 :(得分:0)

另一种可能的选择是直接从FlatFileItemWriter扩展MyWriter:

public class MyWriter extends FlatFileItemWriter<String> implements FlatFileFooterCallback, FlatFileHeaderCallback{
private static Logger log = Logger.getLogger(MyWriter.class);

private int recordCount = 0;
private String stepContext;

public void writeFooter(Writer writer) throws IOException {
    writer.write("#" + recordCount);
}

public void writeHeader(Writer writer) throws IOException {
    writer.write("#" + StringUtil.getSysDate());
}

public void afterPropertiesSet() {
  setFooterCallback(this);
  setHeaderCallback(this);
  super.afterPropertiesSet();
}

public void write(List<? extends String> list) throws Exception {
    super.write(list);
    recordCount += list.size();
}   

}

XML中的配置如下所示:

<bean id="myFinalCustomItemWriter" class="my.process.MyWriter" scope="step">
    <property name="resource" value="${test.file3}" />
    <property name="lineAggregator">
        <bean        class="org.springframework.batch.item.file.transform.PassThroughLineAggregator" />
    </property>
    <property name="stepContext" value="#{stepExecution.stepName}" />
</bean>