Spring Batch:从未调用过FlatFileItemWriter标头 [英] Spring batch : FlatFileItemWriter header never called

查看:5
本文介绍了Spring Batch:从未调用过FlatFileItemWriter标头的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的FlatFileItemWriter回调有一个奇怪的问题。 我有一个实现FlatFileFooterCallback和FlatFileHeaderCallback的自定义ItemWriter。因此,我在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;
}

步骤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和Wire方法中包含经典内容。

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 = "
";
        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 = "
";
        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);
    }
}

当我运行我的批处理时,我只有每个城市(写入方法部分)和脚注行的数据。如果我注释WRITE方法和页脚回调的整个内容,我仍然没有标题行。我尝试在标头回调中添加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

奇怪的是,以前我的页眉可以正常工作,当时我同时添加了页脚和页眉回调。我没有更改它们,我也不知道我在代码中做了什么来"破坏"我的头回调……当然,除了我的第一个代码,我别无选择。因为我现在才看到我的头文件消失了(我检查了我的最后几个文件,看起来我的头文件丢失了一段时间,但我没有看到它),所以我不能只是删除我的修改来查看它何时/为什么会发生。

您有什么办法解决这个问题吗?

谢谢

推荐答案

使用Java配置时,最好尽可能返回最具体的类型(与Java编程中通常要求您做的相反)。在本例中,您的编写器返回ItemWriter,但属于步骤作用域。因此,创建了一个代理,它只能看到您的Java配置返回的类型,在本例中为ItemWriter,并且不公开ItemStream接口上的方法。如果您返回CityItemWriter,我希望一切正常。

这篇关于Spring Batch:从未调用过FlatFileItemWriter标头的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆