Spring批处理:从不调用FlatFileItemWriter头

时间:2015-03-31 09:30:50

标签: spring-batch

我的FlatFileItemWriter回调有一个奇怪的问题。 我有一个自定义ItemWriter实现FlatFileFooterCallback和FlatFileHeaderCallback。因此,我在我的FlatFileItemWriter中设置了页眉和页脚回调,如下所示:

ItemWriter Bean

@Bean
@StepScope
public ItemWriter<CityItem> writer(FlatFileItemWriter<CityProcessed> flatWriter, @Value("#{jobExecutionContext[inputFile]}") String inputFile) {
        CityItemWriter itemWriter = new CityItemWriter();
        flatWriter.setHeaderCallback(itemWriter);
        flatWriter.setFooterCallback(itemWriter);
        itemWriter.setDelegate(flatWriter);
        itemWriter.setInputFileName(inputFile);
        return itemWriter;
}

FlatFileItemWriter Bean

@Bean
@StepScope
public FlatFileItemWriter<CityProcessed> flatFileWriterArchive(@Value("#{jobExecutionContext[outputFileArchive]}") String outputFile) {
    FlatFileItemWriter<CityProcessed> flatWriter = new FlatFileItemWriter<CityProcessed>();
    FileSystemResource isr;
    isr = new FileSystemResource(new File(outputFile));
    flatWriter.setResource(isr);
    DelimitedLineAggregator<CityProcessed> aggregator = new DelimitedLineAggregator<CityProcessed>();
    aggregator.setDelimiter(";");
    BeanWrapperFieldExtractor<CityProcessed> beanWrapper = new BeanWrapperFieldExtractor<CityProcessed>();
    beanWrapper.setNames(new String[]{
        "country", "name", "population", "popUnder25", "pop25To50", "pop50to75", "popMoreThan75"
    });
    aggregator.setFieldExtractor(beanWrapper);
    flatWriter.setLineAggregator(aggregator);
    flatWriter.setEncoding("ISO-8859-1");
    return flatWriter;
}

Step Bean

@Bean
public Step stepImport(StepBuilderFactory stepBuilderFactory, ItemReader<CityFile> reader, ItemWriter<CityItem> writer, ItemProcessor<CityFile, CityItem> processor,
    @Qualifier("flatFileWriterArchive") FlatFileItemWriter<CityProcessed> flatFileWriterArchive, ExecutionContextPromotionListener executionContextListener) {
    return stepBuilderFactory.get("stepImport").<CityFile, CityItem> chunk(10).reader(reader(null)).processor(processor).writer(writer).stream(flatFileWriterArchive)
        .listener(executionContextListener).build();
}

我在writeFooter,writeHeader和write方法中都有经典内容。

ItemWriter代码

public class CityItemWriter implements ItemWriter<CityItem>, FlatFileFooterCallback, FlatFileHeaderCallback, ItemStream {
    private FlatFileItemWriter<CityProcessed> writer;
    private static int totalUnknown = 0;
    private static int totalSup10000 = 0;
    private static int totalInf10000 = 0;
    private String inputFileName = "-";

    public void setDelegate(FlatFileItemWriter<CityProcessed> delegate) {
        writer = delegate;
    }

    public void setInputFileName(String name) {
        inputFileName = name;
    }

    private Predicate<String> isNullValue() {
        return p -> p == null;
    }

    @Override
    public void write(List<? extends CityItem> cities) throws Exception {
        List<CityProcessed> citiesCSV = new ArrayList<>();
        for (CityItem item : cities) {
             String populationAsString = "";
             String less25AsString = "";
             String more25AsString = "";
            /*
             * Some processing to get total Unknown/Sup 10000/Inf 10000
             * and other data
             */
            // Write in CSV file
            CityProcessed cre = new CityProcessed();
            cre.setCountry(item.getCountry());
            cre.setName(item.getName());
            cre.setPopulation(populationAsString);
            cre.setLess25(less25AsString);
            cre.setMore25(more25AsString);
            citiesCSV.add(cre);
        }
        writer.write(citiesCSV);
    }

    @Override
    public void writeFooter(Writer fileWriter) throws IOException {
        String newLine = "\r\n";
        String totalUnknown= "Subtotal:;Unknown;" + String.valueOf(nbUnknown) + newLine;
        String totalSup10000 = ";Sum Sup 10000;" + String.valueOf(nbSup10000) + newLine;
        String totalInf10000 = ";Sum Inf 10000;" + String.valueOf(nbInf10000) + newLine;
        String total = "Total:;;" + String.valueOf(nbSup10000 + nbInf10000 + nbUnknown) + newLine;
        fileWriter.write(newLine);
        fileWriter.write(totalUnknown);
        fileWriter.write(totalSup10000);
        fileWriter.write(totalInf10000);
        fileWriter.write(total );
    }

    @Override
    public void writeHeader(Writer fileWriter) throws IOException {
        String newLine = "\r\n";
        String firstLine= "FILE PROCESSED ON: ;" + new SimpleDateFormat("MM/dd/yyyy").format(new Date()) + newLine;
        String secondLine= "Filename: ;" + inputFileName + newLine;
        String colNames= "Country;Name;Population...;...having less than 25;...having more than 25";
        fileWriter.write(firstLine);
        fileWriter.write(secondLine);
        fileWriter.write(newLine);
        fileWriter.write(colNames);
    }

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

    @Override
    public void open(ExecutionContext context) throws ItemStreamException {
        writer.open(context);
    }

    @Override
    public void update(ExecutionContext context) throws ItemStreamException {
        writer.update(context);
    }
}

当我运行我的批处理时,我只有每个城市的数据(写方法部分)和页脚行。如果我评论写入方法和页脚回调的全部内容,我仍然没有标题行。我试图在我的标题回调中添加一个System.out.println()文本,看起来它从未被调用。

以下是我的批处理生成的CSV文件示例:

France;Paris;2240621;Unknown;Unknown
France;Toulouse;439553;Unknown;Unknown
Spain;Barcelona;1620943;Unknown;Unknown
Spain;Madrid;3207247;Unknown;Unknown
[...]
Subtotal:;Unknown;2
;Sum Sup 10000;81
;Sum Inf 10000;17
Total:;;100

奇怪的是,我添加了页眉和页眉回调之前我的标题曾经工作过。我没有改变它们,我也没有看到我在我的代码中做了什么来打破&#34;我的标题回调...当然,我没有保存我的第一个代码。因为我现在才看到我的标题已经消失了(我检查了我的几个最后文件,看起来我的标题丢失了一段时间但是我没有看到它),我不能删除我的修改看看何时/为什么会发生。

你有什么想法解决这个问题吗?

由于

1 个答案:

答案 0 :(得分:3)

当您按原样使用Java配置时,最好返回最具体的类型(与您在java编程中通常要做的相反)。在这种情况下,您的作者正在返回ItemWriter,但步骤作用域。因此,创建了一个只能看到java配置返回的类型的代理,在这种情况下是ItemWriter并且不公开ItemStream接口上的方法。如果你返回CityItemWriter,我希望事情能够奏效。

相关问题