微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

java – 从tasklet步骤添加参数到作业上下文,并在Spring Batch的后续步骤中使用

现在,我使用jobParameters来获取我的FlatFileItemReader和FlatFileItemWriter的文件名.可以测试我的批次,但我的目标是在某个目录中读取一个文件(该目录中只有这个文件),文件名可能会改变.输出文件名应该取决于输入的文件名.

因此,我想到为我的工作添加一个新的步骤,这一步将通过搜索好的目录并查找文件来设置输出和输入文件名.我从Spring Doc和this thread从SO读了Passing Data to Future Steps,但是我不能使它工作,这些文件总是“null”.

首先,我定义了以下tasklet

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

然后,我添加了promotionListener bean

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

我通过我的FlatFileItemWriter定义中的jobExecutionContext更改了jobParameters(我没有改变一行代码本身)

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

添加了我的tasklet bean

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

我创建了一个新的步骤来添加我的工作申报

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

现在,FlatFileItemReader仍然使用jobParameters值,我想让我的FlatFileItemWriter首先工作.我收到以下错误

[...]    
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

我试图用@JobScope替换@StepScope注释;将我的参数直接插入到jobExecutionContext(JobExecutionListener)中,而不是使用StepContext promotionListener …没有任何工作.当我尝试创建FlatFileItemWriter时,资源文件始终为空.

我失踪了什么

谢谢你的帮助.

解决方法

tasklet中,你可以使用ChunkContext,所以你不需要@BeforeStep,你可以删除它(在我的配置中,它根本没有被调用,当你把它看作一个动作步骤并没有什么意义,但是我不会看NPE,所以猜测这部分工作).我们用两种方法之一解决了:

>你可以使用chunkContext.getStepContext()直接将tasklet中的任何参数添加到作业ExecutionContext中.getStepExecution().getJobExecution().getExecutionContext().put(“inputFile”,inputFilename);>您可以将ExecutionContextPromotionListener添加tasklet步骤,然后执行chunkContext.getStepContext().getStepExecution().getExecutionContext().put(“inputFile”,inputFilename);

原文地址:https://www.jb51.cc/java/123931.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐