Agregue el parámetro al contexto del trabajo desde el paso de tarea y utilícelo en pasos posteriores en Spring Batch
Por ahora, estoy usando jobParameters para obtener los nombres de archivo para mi FlatFileItemReader y FlatFileItemWriter. Está bien para probar mi lote, pero mi objetivo es leer un archivo en algún directorio (solo hay este archivo en este directorio) y el nombre del archivo puede cambiar. El nombre del archivo de salida debe depender del nombre del archivo de entrada.
Por lo tanto, pensé en agregar un nuevo paso a mi trabajo, y este paso establecerá los nombres de los archivos de entrada y de salida buscando en el directorio correcto y buscando el archivo en él. Yo leoPasar datos a pasos futuros de Spring Doc, yeste hilo de SO, pero no puedo hacer que funcione, los archivos siempre son "nulos".
Primero, he definido el siguiente 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;
}
}
Luego, agregué el bean promocionista
@Bean
public ExecutionContextPromotionListener promotionListener() {
ExecutionContextPromotionListener listener = new ExecutionContextPromotionListener();
listener.setKeys(new String[]{
"inputFile", "outputFile"
});
return listener;
}
Cambié los parámetros de trabajo por un jobExecutionContext en mi definición FlatFileItemWriter (no cambié una sola línea al código en sí)
@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;
}
Agregué mi bean Tasklet
@Bean
public SettingFilenamesTasklet settingFilenames() {
return new SettingFilenamesTasklet();
}
Y creé un nuevo Paso para agregar en mi declaración de trabajo
@Bean
public Step stepSettings(StepBuilderFactory stepBuilderFactory, SettingFilenamesTasklet tasklet, ExecutionContextPromotionListener listener) {
return stepBuilderFactory.get("stepSettings").tasklet(tasklet).listener(listener).build();
}
Por ahora, FlatFileItemReader todavía usa el valor jobParameters, quiero que mi FlatFileItemWriter funcione primero. Obtuve el siguiente 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
Traté de reemplazar la anotación @StepScope por @JobScope; poner mis parámetros directamente en jobExecutionContext (+ JobExecutionListener) en lugar de usar StepContext + promotionListener ... Nada funciona. El archivo de recursos siempre es nulo cuando intento crear FlatFileItemWriter.
Qué me estoy perdiendo ?
Gracias por tu ayuda.