FlatFileItemWriter仅在数据存在时写入标头

时间:2016-09-26 19:59:32

标签: spring-batch

只有在存在某些数据时才有将头写入文件的任务,换句话说,如果读者没有返回任何文件,则该文件应该为空。

不幸的是,版本3.0.7中的FlatFileItemWriter实现只有私有访问字段和方法以及存储有关编写过程的所有信息的嵌套类,所以我不能只采用并覆盖write()方法。我需要复制粘贴几乎所有FlatFileItemWriter的内容来添加一小段新功能。

有任何想法如何在Spring Batch中更优雅地实现这一目标吗?

3 个答案:

答案 0 :(得分:1)

所以,终于找到了一个不那么优雅的解决方案。

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

我仅为标题使用单独的行聚合器,但可以扩展解决方案以使用多个聚合器。

同样在我的情况下,标题只是预定义的字符串,因此我默认使用PassThroughLineAggregator只返回我的字符串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(),则存在一些数据。

答案 1 :(得分:0)

我正在考虑如下方式。

  1. BeforeStep()(或Tasklet)如果根本没有数据,则设置一个标记,例如&#34; noData&#34;是真的&#39;。否则将是&#39; false&#39;

  2. 你有2个作家,一个有Header,另一个没有Header。在这种情况下,您可以将基本Writer充当父级,然后2个写入者继承它。它们之间唯一的区别是一个带Header,一个没有HeaderCallBack。

  3. 根据标记,您可以切换到带有标题的&#39; Writer&#39;或者没有标题的作家&#39;

  4. 谢谢, Nghia酒店

答案 2 :(得分:0)

在你的作家中试试这个

writer.setShouldDeleteIfEmpty(true);

如果您没有数据,则没有文件。 在其他情况下,您可以编写标题和项目