Spring Batch Writer将Map <Key,Values>写入文件

时间:2020-08-24 19:41:28

标签: spring spring-batch

我正在使用Spring批处理来开发CSV feed文件。我曾使用类似于下面给出的编写器来生成我的输出文件。

     @Bean
public FlatFileItemWriter<CustomObj> writer() 
{

    BeanWrapperFieldExtractor<CustomObj> extractor = new BeanWrapperFieldExtractor<>();
    extractor.setNames(new String[] {"name", "emailAddress", "dob"});
    
    DelimitedLineAggregator<CustomObj> lineAggregator = new DelimitedLineAggregator<>();
    lineAggregator.setDelimiter(";");

    FieldExtractor<CustomObj> fieldExtractor = createStudentFieldExtractor();
    lineAggregator.setFieldExtractor(fieldExtractor);
    
    FlatFileItemWriter<CustomObj> writer = new FlatFileItemWriter<>();
    writer.setResource(outputResource);
    writer.setAppendAllowed(true);
    //writer.setHeaderCallback(headerCallback);
    writer.setLineAggregator(lineAggregator);
    return writer;
}

输出

name;emailAddress;dob
abc;abc@xyz.com;10-10-20

但是现在我们需要使该writer具有通用性,这样我们就不再传递对象,而是传递Map ,并且对象值现在存储在键值对的Map中 例如:name-> abc,emailAddress-> abc@xyz.com,dob-> 10-10-20

我们尝试使用类似于以下内容的作者, 但是这里的问题是,由于没有设置FieldExtractor,因此标头和值可能不同步。

PassThroughFieldExtractor只是以任意顺序传递集合(地图)中的所有值。即使地图包含更多字段,它也会打印所有字段。 在这种情况下,标题和值不绑定在一起。 有什么方法可以实现自定义字段提取器,该方法可以确保即使我们更改标题的顺序,值的顺序仍与标题保持一致。

   @Bean
public FlatFileItemWriter<Map<String,String>> writer() 
{

    DelimitedLineAggregator<Map<String,String>> lineAggregator = new DelimitedLineAggregator<>();
    lineAggregator.setDelimiter(";");

    FieldExtractor<Map<String,String>> fieldExtractor = createStudentFieldExtractor();
    lineAggregator.setFieldExtractor(new  PassThroughFieldExtractor<>());
    
    FlatFileItemWriter<Map<String,String>> writer = new FlatFileItemWriter<>();
    writer.setResource(outputResource);
    writer.setAppendAllowed(true);
    writer.setLineAggregator(lineAggregator);
    return writer;
}

输出

name;emailAddress;dob
abc@xyz.com;abc;10-10-20

预期产量

case 1: 
name;emailAddress;dob
abc;abc@xyz.com;10-10-20

case 2: 
emailAddress;dob
abc@xyz.com;10-10-20 

1 个答案:

答案 0 :(得分:0)

您需要一个自定义字段集提取器,该提取器以与标头相同的顺序从地图中提取值。 Spring Batch没有提供这种提取器,因此您需要自己实现。例如,您可以在构造时将标头传递到提取器,并根据标头顺序从地图中提取值。