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.

Pouvez-vous essayer d'ajouter @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