从FlatFileItemReader LineMapper访问平面文件的名称

时间:2017-03-29 15:16:50

标签: java spring spring-boot spring-batch

我需要能够访问正在读取当前行的平面文件的名称。我们正在移植一个应用程序,当前的一些流程需要这些信息。

这是我目前的配置:

private FlatFileItemReader<Invoice> invoiceFlatFileItemReader() throws Exception {
    FlatFileItemReader<Invoice> reader = new FlatFileItemReader<>();
    reader.setLinesToSkip(1); // header row
    reader.setLineMapper(new InvoiceLineMapper());
    reader.afterPropertiesSet();

    return reader;
}

InvoiceLineMapper:

public class InvoiceLineMapper implements LineMapper<Invoice> {

    @Override
    public Invoice mapLine(String line, int lineNumber) throws Exception {
        String[] fields = line.split(",");
        ArrayList<String> fieldList = new ArrayList<>();

        for (int i = 0; i < fields.length; i++) {
            fieldList.add(fields[i].replaceAll("\"", "");
        }

        Invoice invoice = new Invoice();

        invoice.setCustomerNumber(Integer.parseInt(fieldList.get(0));
        invoice.setCustomerName(fieldList.get(1));

        // set other things and stuff...

        //Need to be able to set the file name on the model here
        invoice.setFileName(theFileName);
    }
}

我通过invoiceFlatFileItemReader()

委托给MultiResourceItemReader
@Bean
public ItemReader<Invoice> invoiceItemReader() throws Exception {
    ResourcePatternResolver resolver = new PathMatchingResourcePatterResolver(this.getClass().getClassLoader());

    // currently being loaded from the classpath, eventually will be read from S3...that comes later
    Resource[] resources = resolver.getResources("classpath*:**/InvoiceList*.csv*"); 

    MultiResourceItemReader<Invoice> reader = new MultiResourceItemReader<>();
    reader.setResources(resources);
    reader.setDelegate(invoiceFlatFileItemReader());

    return reader;
}

如何从链中传递到我可以在InvoiceLineMapper类中访问它的资源的名称,并将其添加到模型中(稍后将使用{{1}保留该模型})吗

2 个答案:

答案 0 :(得分:1)

您的项目可以实现一个界面ResourceAware。如果它确实实现了该接口,则在使用MultiResourceItemReader时,将自动为您注入资源。您可以在此处的文档中详细了解ResourceAware界面:http://docs.spring.io/spring-batch/apidocs/org/springframework/batch/item/ResourceAware.html

答案 1 :(得分:1)

以下是我最终要做的事情,只是将MultiItemResourceReader传递到链中,以便我可以在行映射器中调用getCurrentResource()

@Bean
public ItemReader<Invoice> invoiceItemReader() throws Exception {
    ResourcePatternResolver resolver = new PathMatchingResourcePatterResolver(this.getClass().getClassLoader());

    // currently being loaded from the classpath, eventually will be read from S3...that comes later
    Resource[] resources = resolver.getResources("classpath*:**/InvoiceList*.csv*"); 

    MultiResourceItemReader<Invoice> reader = new MultiResourceItemReader<>();
    reader.setResources(resources);
    reader.setDelegate(invoiceFlatFileItemReader(reader));

    return reader;
}

private FlatFileItemReader<Invoice> invoiceFlatFileItemReader(MultiResourceItemReader delegator) throws Exception {
    FlatFileItemReader<Invoice> reader = new FlatFileItemReader<>();
    reader.setLinesToSkip(1); // header row
    reader.setLineMapper(new InvoiceLineMapper(delegator));
    reader.afterPropertiesSet();

    return reader;
}

然后在InvoiceLineMapper

public class InvoiceLineMapper implements LineMapper<Invoice> {

    private MultiResourceItemReader delegator;

    public InvoiceLineMapper(MultiResourceItemReader delegator) {
         this.delegator = delegator;
    }

    @Override
    public Invoice mapLine(String line, int lineNumber) throws Exception {
        String[] fields = line.split(",");
        ArrayList<String> fieldList = new ArrayList<>();

        for (int i = 0; i < fields.length; i++) {
            fieldList.add(fields[i].replaceAll("\"", "");
        }

        Invoice invoice = new Invoice();

        invoice.setCustomerNumber(Integer.parseInt(fieldList.get(0));
        invoice.setCustomerName(fieldList.get(1));

        // set other things and stuff...

        Resource currentResource = delegator.getCurrentResource();
        String[] fileName = currentResource.getFilename().split("/");

        invoice.setFileName(filename[filename.length - 1]);

        return invoice;
    }
}