• Jobs
  • About Us
  • professionals
    • Home
    • Jobs
    • Courses and challenges
  • business
    • Home
    • Post vacancy
    • Our process
    • Pricing
    • Assessments
    • Payroll
    • Blog
    • Sales
    • Salary Calculator

0

291
Views
Accessing name of flat file from FlatFileItemReader LineMapper

I have a need to be able to access the name of the flat file that the current line being read is from. We are porting an application and some processes that are currently in place require this information.

Here is my current configuration:

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

I am delegating to the invoiceFlatFileItemReader() via a 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;
}

How can I get the name of the resource passed down the chain to where I can access it in the InvoiceLineMapper class and add it to the model (which later gets persisted with a RepositoryItemWriter)?

about 3 years ago · Santiago Trujillo
2 answers
Answer question

0

There is an interface ResourceAware that your item can implement. If it does implement that interface, when using MultiResourceItemReader, the resource will be injected automatically for you. You can read more about the ResourceAware interface in the documentation here: http://docs.spring.io/spring-batch/apidocs/org/springframework/batch/item/ResourceAware.html

about 3 years ago · Santiago Trujillo Report

0

Here's what I ended up doing, just passing the MultiItemResourceReader down the chain so that I could call getCurrentResource() in the line mapper:

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

And then in 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;
    }
}
about 3 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Our process Sales
Legal
Terms and conditions Privacy policy
© 2025 PeakU Inc. All Rights Reserved.

Andres GPT

Recommend me some offers
I have an error