Java – add parameters to the job context from the tasklet step and use them in subsequent steps of spring batch

Now, I use jobparameters to get the file names of my flatfileitemreader and flatfileitemwriter My batch can be tested, but my goal is to read a file in a directory (there is only this file in the directory), and the file name may change The output file name should depend on the input file name

Therefore, I thought of adding a new step to my work, which will set the output and input file names by searching a good directory and looking for files I read passing data to future steps from spring doc and this thread from so, but I can't make it work. These files are always "null"

First, I defined the following tasklets

public class SettingFilenamesTasklet implements Tasklet {

    private StepExecution stepExecution;

    @Override
    public RepeatStatus execute(StepContribution contribution,ChunkContext chunkContext) throws Exception {
        // TODO Search folder and set real filenames
        String inputFilename = "D:/TestInputFolder/dataFile.csv";
        String outputFilename = "D:/TestOutputFolder/dataFile-processed.csv";
        ExecutionContext stepContext = stepExecution.getExecutionContext();
        stepContext.put("inputFile",inputFilename);
        stepContext.put("outputFile",outputFilename);
        return RepeatStatus.FINISHED;
    }

    @BeforeStep
    public void saveStepExecution(StepExecution stepExec) {
        stepExecution = stepExec;
    }
}

Then, I added the promotionlistener bean

@Bean
public ExecutionContextPromotionListener promotionListener() {
    ExecutionContextPromotionListener listener = new ExecutionContextPromotionListener();
    listener.setKeys(new String[]{
            "inputFile","outputFile"
    });
    return listener;
}

I changed jobparameters through jobexecutioncontext in my flatfileitemwriter definition (I didn't change a line of code itself)

@Bean
@StepScope
public FlatFileItemWriter<RedevableCRE> flatFileWriter(@Value("#{jobExecutionContext[outputFile]}") String outputFile) {
    FlatFileItemWriter<Employee> flatWriter = new FlatFileItemWriter<Employee>();
    FileSystemResource isr;
    isr = new FileSystemResource(new File(outputFile));
    flatWriter.setResource(isr);
    DelimitedLineAggregator<RedevableCRE> aggregator = new DelimitedLineAggregator<RedevableCRE>();
    aggregator.setDelimiter(";");
    BeanWrapperFieldExtractor<RedevableCRE> beanWrapper = new BeanWrapperFieldExtractor<RedevableCRE>();
    beanWrapper.setNames(new String[]{
        "id","firstName","lastName","phone","address"
    });
    aggregator.setFieldExtractor(beanWrapper);
    flatWriter.setLineAggregator(aggregator);
    flatWriter.setEncoding("ISO-8859-1");
    return flatWriter;
}

I added my tasklet bean

@Bean
public SettingFilenamesTasklet settingFilenames() {
    return new SettingFilenamesTasklet();
}

I created a new step to add my work declaration

@Bean
public Step stepSettings(StepBuilderFactory stepBuilderFactory,SettingFilenamesTasklet tasklet,ExecutionContextPromotionListener listener) {
    return stepBuilderFactory.get("stepSettings").tasklet(tasklet).listener(listener).build();
}

At present, the flatfileitemreader still uses the jobparameters value. I want my flatfileitemwriter to work first I received the following error:

[...]    
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.batch.item.file.FlatFileItemWriter]: Factory method 'flatFileWriter' threw exception; nested exception is java.lang.NullPointerException
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:189)
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:591)
    ... 87 common frames omitted
Caused by: java.lang.NullPointerException: null
    at java.io.File.<init>(UnkNown Source)
    at batchTest.BatchConfiguration.flatFileWriter(BatchConfiguration.java:165)
    at batchTest.BatchConfiguration$$EnhancerBySpringcglib$$5d415889.cglib$flatFileWriter$1(<generated>)
    at batchTest.BatchConfiguration$$EnhancerBySpringcglib$$5d415889$$FastClassBySpringcglib$$969a8527.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:312)
    at batchTest.BatchConfiguration$$EnhancerBySpringcglib$$5d415889.flatFileWriter(<generated>)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(UnkNown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(UnkNown Source)
    at java.lang.reflect.Method.invoke(UnkNown Source)
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:162)
    ... 88 common frames omitted

I tried to replace the @ stepscope annotation with @ jobscope; Inserting my parameters directly into jobexecutioncontext (jobexecutionlistener) instead of using stepcontext promotionlistener... Doesn't work When I try to create a flatfileitemwriter, the resource file is always empty

I'm missing what

Thanks for your help.

Solution

In tasklet, you can use chunkcontext, so you don't need @ beforestep. You can delete it (in my configuration, it's not called at all. It doesn't make sense when you think of it as an action step, but I won't look at NPE, so I guess this division of work) We solved this problem in one of two ways:

>You can use chunkcontext Getstepcontext () directly adds any parameters in the tasklet to the job ExecutionContext getStepExecution(). getJobExecution(). getExecutionContext(). put(“inputFile”,inputFilename);> You can add executioncontextpromotionlistener to the tasklet step, and then execute chunkcontext getStepContext(). getStepExecution(). getExecutionContext(). put(“inputFile”,inputFilename);

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>