我正在使用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
我们尝试使用类似于以下内容的作者, 但是这里的问题是,由于没有设置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
答案 0 :(得分:0)
您需要一个自定义字段集提取器,该提取器以与标头相同的顺序从地图中提取值。 Spring Batch没有提供这种提取器,因此您需要自己实现。例如,您可以在构造时将标头传递到提取器,并根据标头顺序从地图中提取值。