如何创建一个通用的 FlatFileItemReader 来读取具有不同 headers 的 CSV 文件?
How to create a generic FlatFileItemReader to read CSV files with different headers?
我正在创建一个作业,它将根据输入参数读取和处理不同的 .csv 文件。有 3 种不同类型的 .csv 文件,具有不同的 headers。我想使用通用 FlatFileItemReader
将文件的每一行映射到 POJO。
每种类型的文件都有自己的 POJO 实现,并且所有 "File Specific POJOs" 都是从抽象 GenericFilePOJO
继承而来的。
一个 tasklet 将首先读取输入参数来决定需要读取哪种文件类型,并构造一个具有适当 header 列的 LineTokenizer。它将此信息放在 infoHolder 中,以便在 reader 步骤检索。
@Bean
public FlatFileItemReader<GenericFilePOJO> reader() {
FlatFileItemReader<RawFile> reader = new FlatFileItemReader<GenericFilePOJO>();
reader.setLinesToSkip(1); // header
reader.setLineMapper(new DefaultLineMapper() {
{
// The infoHolder will contain the file-specific LineTokenizer
setLineTokenizer(infoHolder.getLineTokenizer());
setFieldSetMapper(new BeanWrapperFieldSetMapper<GenericFilePOJO>() {
{
setTargetType(GenericFilePOJO.class);
}
});
}
});
return reader;
}
尽管返回 GenericFilePOJO
,这个 reader 可以处理不同的文件特定 POJO 吗?
您写道:
A tasklet
will first read the input parameter to decide which file
type needs to be read.
因为 tasklet
或 infoHolder
知道文件类型,您可以实现特定 FieldSetMapper
实例的创建。
这是一个如何实现的演示示例:
public class Solution<T extends GenericFilePOJO> {
private InfoHolder infoHolder = new InfoHolder();
@Bean
public FlatFileItemReader<T> reader()
{
FlatFileItemReader<T> reader = new FlatFileItemReader<T>();
reader.setLinesToSkip(1);
reader.setLineMapper(new DefaultLineMapper() {
{
setLineTokenizer(infoHolder.getLineTokenizer());
setFieldSetMapper(infoHolder.getFieldSetMapper());
}
});
return reader;
}
private class InfoHolder {
DelimitedLineTokenizer getLineTokenizer() {
return <some already existent logic>;
}
FieldSetMapper<T> getFieldSetMapper() {
if (some condition for specific file POJO 1){
return new BeanWrapperFieldSetMapper<T>() {
{
setTargetType(FileSpecificPOJO_1.class);
}
};
} else if (some condition for specific file POJO 2){
return new BeanWrapperFieldSetMapper<T>() {
{
setTargetType(FileSpecificPOJO_2.class);
}
};
}
}
}
}
我正在创建一个作业,它将根据输入参数读取和处理不同的 .csv 文件。有 3 种不同类型的 .csv 文件,具有不同的 headers。我想使用通用 FlatFileItemReader
将文件的每一行映射到 POJO。
每种类型的文件都有自己的 POJO 实现,并且所有 "File Specific POJOs" 都是从抽象 GenericFilePOJO
继承而来的。
一个 tasklet 将首先读取输入参数来决定需要读取哪种文件类型,并构造一个具有适当 header 列的 LineTokenizer。它将此信息放在 infoHolder 中,以便在 reader 步骤检索。
@Bean
public FlatFileItemReader<GenericFilePOJO> reader() {
FlatFileItemReader<RawFile> reader = new FlatFileItemReader<GenericFilePOJO>();
reader.setLinesToSkip(1); // header
reader.setLineMapper(new DefaultLineMapper() {
{
// The infoHolder will contain the file-specific LineTokenizer
setLineTokenizer(infoHolder.getLineTokenizer());
setFieldSetMapper(new BeanWrapperFieldSetMapper<GenericFilePOJO>() {
{
setTargetType(GenericFilePOJO.class);
}
});
}
});
return reader;
}
尽管返回 GenericFilePOJO
,这个 reader 可以处理不同的文件特定 POJO 吗?
您写道:
A
tasklet
will first read the input parameter to decide which file type needs to be read.
因为 tasklet
或 infoHolder
知道文件类型,您可以实现特定 FieldSetMapper
实例的创建。
这是一个如何实现的演示示例:
public class Solution<T extends GenericFilePOJO> {
private InfoHolder infoHolder = new InfoHolder();
@Bean
public FlatFileItemReader<T> reader()
{
FlatFileItemReader<T> reader = new FlatFileItemReader<T>();
reader.setLinesToSkip(1);
reader.setLineMapper(new DefaultLineMapper() {
{
setLineTokenizer(infoHolder.getLineTokenizer());
setFieldSetMapper(infoHolder.getFieldSetMapper());
}
});
return reader;
}
private class InfoHolder {
DelimitedLineTokenizer getLineTokenizer() {
return <some already existent logic>;
}
FieldSetMapper<T> getFieldSetMapper() {
if (some condition for specific file POJO 1){
return new BeanWrapperFieldSetMapper<T>() {
{
setTargetType(FileSpecificPOJO_1.class);
}
};
} else if (some condition for specific file POJO 2){
return new BeanWrapperFieldSetMapper<T>() {
{
setTargetType(FileSpecificPOJO_2.class);
}
};
}
}
}
}