Ajouter un paramètre à l'emploi cadre de tasklet étape et utiliser dans les étapes ultérieures de Spring Batch
Pour l'instant, je suis en utilisant jobParameters pour obtenir les noms de fichiers à la fois pour mon FlatFileItemReader et FlatFileItemWriter. C'est bien pour tester mon lot, mais mon but est de lire un fichier dans un répertoire (il n'y a que ce fichier dans ce répertoire) et le nom de fichier peut changer. Le nom de fichier de sortie doit dépendre du fichier d'entrée.
Donc, j'ai pensé à l'ajout d'une nouvelle étape de mon travail, et cette étape permettra de définir à la fois d'entrée et de sortie des noms de fichier en recherchant le bon répertoire et recherchez le fichier. J'ai lu Le passage des Données aux Étapes à venir de Printemps Doc, et ce fil de la SORTE, mais je ne peux pas le faire fonctionner, les fichiers sont toujours la valeur "null".
Tout d'abord, j'ai défini les suivantes 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;
}
}
Ensuite, j'ai ajouté le promotionListener bean
@Bean
public ExecutionContextPromotionListener promotionListener() {
ExecutionContextPromotionListener listener = new ExecutionContextPromotionListener();
listener.setKeys(new String[]{
"inputFile", "outputFile"
});
return listener;
}
J'ai changé le jobParameters par un jobExecutionContext dans mon FlatFileItemWriter définition (je ne l'ai pas changer une seule ligne du code lui-même)
@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;
}
J'ai ajouté mon Tasklet bean
@Bean
public SettingFilenamesTasklet settingFilenames() {
return new SettingFilenamesTasklet();
}
Et j'ai créé une nouvelle Étape pour ajouter dans mon travail, déclaration
@Bean
public Step stepSettings(StepBuilderFactory stepBuilderFactory, SettingFilenamesTasklet tasklet, ExecutionContextPromotionListener listener) {
return stepBuilderFactory.get("stepSettings").tasklet(tasklet).listener(listener).build();
}
Pour l'instant, la FlatFileItemReader utilise toujours le jobParameters valeur, je veux faire mon FlatFileItemWriter travail d'abord. J'obtiens l'erreur suivante :
[...]
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
J'ai essayé de remplacer le @StepScope annotation par @JobScope ; de mettre mes paramètres directement dans jobExecutionContext (+ JobExecutionListener) au lieu d'utiliser StepContext + promotionListener... Rien ne fonctionne. Le fichier de ressources est toujours la valeur null lorsque j'essaie de créer le FlatFileItemWriter.
Ce qui me manque ?
Merci pour votre aide.
@BeforeStep
à votre écrivain et place un point d'arrêt pour vérifier ce qui est dans stepExecution.getExecutionContext()
et stepExecution.getJobExecution().getExecutionContext()
? Supprimer @Value
de sorte que vous pouvez commencer votre travail pour le moment.Il semble que mon code n'a même pas d'exécuter la
@BeforeStep
méthode que j'ai écrit... j'ai créé une classe étendant FlatFileItemWriter afin de tester ce que vous avez dit (je ne vois pas comment ajouter un @BeforeStep
dans le lot de configuration contraire), que j'instancie la place du générique FlatFileItemWriter dans mon code. Mon débogueur ne s'arrête pas sur les points d'arrêt, j'ai mis en...OriginalL'auteur Carrm | 2015-03-18
Vous devez vous connecter pour publier un commentaire.
Dans tasklet vous avez
ChunkContext
à votre disposition afin que vous n'avez pas besoin@BeforeStep
, vous pouvez le supprimer (dans ma configuration, il n'est pas appelée à tous, et quand vous pensez à elle comme une étape d'action ne fait pas beaucoup de sens, mais je ne vois pas NPE donc deviner que le cadre de travail). Nous l'avons résolu avec l'un des deux approches:Vous pouvez mettre n'importe quel paramètre de tasklet de travail
ExecutionContext
directement à l'aide dechunkContext.getStepContext().getStepExecution().getJobExecution().getExecutionContext().put("inputFile", inputFilename);
Vous pouvez ajouter
ExecutionContextPromotionListener
à votre tasklet étape et ensuite fairechunkContext.getStepContext().getStepExecution().getExecutionContext().put("inputFile", inputFilename);
Mon erreur : je n'utilisais pas la bonne écoute pour la 2ème solution. Il fonctionne bien, merci !
OriginalL'auteur Nenad Bozic