У меня есть объект вроде (абстрактное описание)

public class Book {
private String name;
private List<Author> authors;
}
public class Author {
private String name;
}

И например

 new Book()
 .setName("Book name1")
 .setAuthors(new ArrayList(Arrays.asList(
      new Author().setName("Author 1"), 
      new Author().setName("Author 2"))));

Пример кода:

@Bean
public FlatFileItemWriter<Book> writer()
{
    FlatFileItemWriter<Book> writer = new FlatFileItemWriter<>();
    writer.setResource(outputResource);
    writer.setAppendAllowed(true);
    writer.setLineAggregator(new DelimitedLineAggregator<Book>() {
        {
            setDelimiter(";");
            setFieldExtractor(new BeanWrapperFieldExtractor<Book>() {
                {
                    setNames(new String[] { "name", "authors" });
                }
            });
        }
    });
    return writer;
}

Так я получаю результат:

Book name1;[Author(authorName=Author 1), Author(authorName=Author 2)]

Но я хочу получить файл csv результата как:

Book name1;Author 1
Book name1;Author 2

Помогите разобраться, как это работает. Заранее спасибо.

0
zond 12 Фев 2021 в 14:15

1 ответ

Лучший ответ

Помогите разобраться, как это работает

BeanWrapperFieldExtractor - это экстрактор полей, который вызывает геттеры для каждого поля вашего входного объекта. Вот выдержка из его Документ Javadoc:

Given an array of property names, it will reflectively call getters on the item
and return an array of all the values.

В вашем случае вызов метода получения поля authors приводит к значению toString() объекта List:

[Author(authorName=Author 1), Author(authorName=Author 2)]

Однако то, что вы пытаетесь сделать, на самом деле является операцией с плоской картой, поскольку вы хотите, чтобы каждая книга ввода была записана в виде нескольких строк, по одной строке для каждого автора. Есть много способов сделать это, один из них описан в Сглаживание результата обработки в весенней партии.

0
Mahmoud Ben Hassine 15 Фев 2021 в 14:48