Spring Batch Writer для записи карты в файл

#spring #spring-batch

#spring #spring-batch

Вопрос:

Я использую пакет Spring для разработки файлов CSV-каналов. Я использовал средство записи, подобное приведенному ниже, для создания моего выходного файла.

      @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
  

Но теперь у нас есть требование сделать эту запись универсальной, чтобы мы больше не передавали объект, вместо этого передавали карту<Строка, String>, и значения объекта теперь хранятся в карте пар ключ-значение
Например: имя-> abc, адрес электронной почты->abc@xyz.com , dob -> 10-10-20

Мы пытались использовать средство записи, аналогичное приведенному ниже, но проблема здесь в том, что из-за отсутствия набора FieldExtractor заголовок и значения могут не синхронизироваться.

PassThroughFieldExtractor просто передает все значения в коллекции (Map) в любом порядке. даже если Карта содержит больше полей, она печатает все поля. Заголовок и значения в этом случае не связаны друг с другом. Есть ли какой-либо способ реализовать пользовательский экстрактор полей, который гарантирует, что даже если мы изменим порядок заголовка, порядок значений останется в соответствии с заголовком.

    @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:

вам нужен пользовательский экстрактор набора полей, который извлекает значения из карты в том же порядке, что и заголовки. Spring Batch не предоставляет такого экстрактора, поэтому вам нужно реализовать его самостоятельно. Например, вы можете передавать заголовки во время построения в экстрактор и извлекать значения из карты в соответствии с порядком заголовков.