FlatFileItemWriter write header 只有在数据存在的情况下

FlatFileItemWriter write header only in case when data is present

只有当某些数据存在时,才有任务将 header 写入文件,换句话说,如果 reader return 编写器创建的任何文件都不应为空。

不幸的是,FlatFileItemWriter 实现在版本 3.0.7 中只有私有访问字段和方法以及嵌套 class 存储有关写入过程的所有信息,所以我不能只获取并覆盖 write() 方法.我需要 copy-paste FlatFileItemWriter 的几乎所有内容来添加一小部分新功能。

知道如何在 Spring 批处理中更优雅地实现这一点吗?

我在想办法如下

  1. BeforeStep()(或一个Tasklet)如果根本没有Data,你设置一个标志,比如"noData"是'true'。否则将是 'false'

  2. 你有2位作者,一位有Header,另一位没有Header。在这种情况下,您可以让一个基本 Writer 作为父级,然后 2 个 writer 继承它。它们之间唯一的区别是一个有Header,一个没有HeaderCallBack。

  3. 根据标志,您可以切换到 'Writer with Header' 或 'Writer without Header'

谢谢, 义亚

于是,终于找到了一个less-more优雅的解决方案。

解决方案是使用LineAggregators,并且在FlatFileItemWriter的当前实现中似乎这只是继承此class时可以使用更安全的一种方法。

我只对 header 使用单独的线路聚合器,但可以扩展该解决方案以使用多个聚合器。

另外在我的例子中 header 只是预定义的字符串,因此我默认使用 PassThroughLineAggregator 只是 return 我的字符串到 FlatFileItemWriter.

public class FlatFileItemWriterWithHeaderOnData extends FlatFileItemWriter {

    private LineAggregator lineAggregator;
    private LineAggregator headerLineAggregator = new PassThroughLineAggregator();

    private boolean applyHeaderAggregator = true;

    @Override
    public void afterPropertiesSet() throws Exception {
        Assert.notNull(headerLineAggregator, "A HeaderLineAggregator must be provided.");
        super.afterPropertiesSet();
    }

    @Override
    public void setLineAggregator(LineAggregator lineAggregator) {
        this.lineAggregator = lineAggregator;
        super.setLineAggregator(lineAggregator);
    }

    public void setHeaderLineAggregator(LineAggregator headerLineAggregator) {
        this.headerLineAggregator = headerLineAggregator;
    }

    @Override
    public void write(List items) throws Exception {
        if(applyHeaderAggregator){
            LineAggregator initialLineAggregator = lineAggregator;
            super.setLineAggregator(headerLineAggregator);
            super.write(getHeaderItems());
            super.setLineAggregator(initialLineAggregator);
            applyHeaderAggregator = false;
        }

        super.write(items);
    }

    private List<String> getHeaderItems() throws ItemStreamException {  
        // your actual implementation goes here
        return Arrays.asList("Id,Name,Details");
    }
}

PS。此解决方案假定如果方法 write() 被调用,则存在一些数据。

在你的作家中试试这个

writer.setShouldDeleteIfEmpty(true);

没有数据就没有文件。 在其他情况下,您写 header 和您的项目