如何创建通用的FlatFileItemReader以读取具有不同标题的CSV文件? [英] How to create a generic FlatFileItemReader to read CSV files with different headers?

查看:72
本文介绍了如何创建通用的FlatFileItemReader以读取具有不同标题的CSV文件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在创建一个作业,该作业将基于输入参数读取和处理不同的.csv文件.有3种不同类型的.csv文件,它们的标题不同.我想使用通用的 FlatFileItemReader 将文件的每一行映射到POJO.

I'm creating a job that will read and process different .csv files based on an input parameter. There are 3 different types of .csv files with different headers. I want to map each line of a file to a POJO using a generic FlatFileItemReader.

每种文件类型都有其自己的POJO实现,并且所有特定于文件的POJO"都从抽象的 GenericFilePOJO 子类化.

Each type of file will have its own POJO implementation, and all "File Specific POJOs" are subclassed from an abstract GenericFilePOJO.

tasklet首先将读取输入参数,以确定需要读取的文件类型,然后使用适当的标题列构造LineTokenizer.它将此信息放置在infoHolder中以在阅读器步骤中进行检索.

A tasklet will first read the input parameter to decide which file type needs to be read, and construct a LineTokenizer with the appropriate header columns. It places this information in the infoHolder for retrieval at the reader step.

@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 ,该读者仍可以处理不同的文件特定POJO吗?

Can this reader handle the different File Specific POJOs despite returning the GenericFilePOJO?

推荐答案

您写道:

tasklet 将首先读取输入参数以确定哪个文件类型需要阅读.

A tasklet will first read the input parameter to decide which file type needs to be read.

由于 tasklet infoHolder 知道文件的类型,因此可以实现创建特定的 FieldSetMapper 实例.

Because the tasklet or infoHolder knows about type of file you can implement the creation of specific FieldSetMapper instance.

这是一个演示示例,该示例如何实现:

This is a demo example how it can be implemented:

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);
                    }
                };
            }
        }
    }
}

这篇关于如何创建通用的FlatFileItemReader以读取具有不同标题的CSV文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆