gpt4 book ai didi

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

转载 作者:搜寻专家 更新时间:2023-10-30 19:59:18 24 4
gpt4 key购买 nike

目前,我正在使用 jobParameters 获取我的 FlatFileItemReader 和 FlatFileItemWriter 的文件名。测试我的批处理没问题,但我的目标是读取某个目录中的文件(该目录中只有这个文件)并且文件名可能会更改。输出文件名应取决于输入文件名。

因此,我考虑在我的工作中添加一个新步骤,这一步将通过搜索好目录并在其中查找文件来设置输出和输入文件名。我读了Passing Data to Future Steps来自 Spring Doc,和 this thread来自 SO,但我无法使其工作,文件始终为“空”。

首先,我定义了以下 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 时,资源文件始终为 null。

我错过了什么?

感谢您的帮助。

最佳答案

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

  1. 您可以直接使用 chunkContext.getStepContext().getStepExecution().getJobExecution().getExecutionContext().put("inputFile ", 输入文件名);

  2. 您可以将 ExecutionContextPromotionListener 添加到您的 tasklet 步骤,然后执行 chunkContext.getStepContext().getStepExecution().getExecutionContext().put("inputFile", inputFilename);

关于java - 从 tasklet 步骤将参数添加到作业上下文,并在 Spring Batch 的后续步骤中使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29118156/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com