从步骤1到下一步的Spring批处理传递资源值

时间:2018-10-18 19:23:59

标签: java spring spring-batch

因此,我的Spring批处理作业分为三个步骤,第一步(任务let)将从共享驱动器中复制文件并将它们存储在spring项目的文件夹中(FileSystems.getDefault()。“ folder_name”)。第二步应该从该文件夹中读取xml文件,并按照业务逻辑进行处理,最后写入数据库。最后一步(tasklet)将删除在步骤1中创建的文件夹。但是我得到的是“ java.lang .IllegalArgumentException:必须设置资源并osbatch.core.step.AbstractStep:作业Job java.lang.NullPointerException中的步骤step1中关闭步骤执行资源时发生异常。”我正在使用 MultiResourceItemReader < / strong>以在第二步中读取文件。有人可以帮忙如何删除此异常,以便按上述逻辑执行批处理。

这是批处理配置-

@Autowired
public TaskletStep taskletStep;

@Autowired
public MyItemReader myItemReader;

@Autowired
public MyItemWriter myItemWriter;

@Autowired
public JobBuilderFactory jobBuilderFactory;

@Autowired
public StepBuilderFactory stepBuilderFactory;

@Bean
public Job job() throws FileNotFoundException, XMLStreamException, URISyntaxException {
    return jobBuilderFactory.get("job")
            .incrementer(new RunIdIncrementer())
            .start(step1()).next(step2())
            .build();
}

@Bean
public Step step1() {
    return stepBuilderFactory.get("step1")
            .tasklet(taskletStep).listener(promotionListener())
            .build();
}

    @Bean
    public ExecutionContextPromotionListener promotionListener() {
            ExecutionContextPromotionListener listener = new ExecutionContextPromotionListener();

            listener.setKeys(new String[] {"someKey" });

            return listener;
    };


@Bean
public Step step2() {
    return stepBuilderFactory.get("step2")
            .<String, String> chunk(1)
            .reader(myItemReader)
            .writer(myItemWriter)
            .build();
}

这是taskletStep

private static FileSystem fileSystem = FileSystems.getDefault();
private String locationSourceNetwork = "E:\\assss\\wfwef.txt";
private ChunkContext chunkContext;
String homeOfficeDirectoryUnzip =  fileSystem.getPath("HOME").toAbsolutePath().toString();
@Override
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {

    //String homeOfficeDirectoryUnzip =  fileSystem.getPath("HOME").toAbsolutePath().toString();
    File file = new File(homeOfficeDirectoryUnzip);

    Path sourceDirectory = Paths.get(locationSourceNetwork);
    //Path targetDirectory = Paths.get(homeOfficeDirectoryUnzip);
    Files.copy(sourceDirectory, file.toPath());
    ExecutionContext stepContext = chunkContext.getStepContext().getStepExecution().getExecutionContext();
    stepContext.put("someKey", homeOfficeDirectoryUnzip);
    return RepeatStatus.FINISHED;
}
@BeforeStep
public void saveStepExecution(ChunkContext chunkContext) {
    this.chunkContext = chunkContext;
    /*ExecutionContext stepContext = this.stepExecution.getExecutionContext();
    stepContext.put("someKey", homeOfficeDirectoryUnzip);*/
}

这是MyItemReader-

私有资源[]资源;

/*@Autowired
ResourcesFactoryBean fileResources;*/

private static String files =  new ClassPathResource("HOME").toString();//FileSystems.getDefault().getPath("HOME").toAbsolutePath().toString();

private Resource[] resources;


@BeforeStep
public void retrieveInterstepData(StepExecution stepExecution) throws IOException {
    JobExecution jobExecution = stepExecution.getJobExecution();
    ExecutionContext jobContext = jobExecution.getExecutionContext();
    ResourcePatternResolver patternResolver = new PathMatchingResourcePatternResolver();
    this.resources = patternResolver.getResources("file:"+jobContext.get("someKey").toString());
}


public MultiResourceItemReader<String> multiResourceItemReader()
        throws FileNotFoundException, XMLStreamException, URISyntaxException {
    MyItemReader resourceItemReader = new MyItemReader();
    resourceItemReader.setResources(resources);
    resourceItemReader.setDelegate(headerXmlReader());
    resourceItemReader.setStrict(false);
    return resourceItemReader;
}

public StaxEventItemReader<String> headerXmlReader()
        throws FileNotFoundException, XMLStreamException, URISyntaxException {
    // TODO Auto-generated method stub

    StaxEventItemReader<String> staxHeaderDataReader = new StaxEventItemReader<String>();
    System.out.println("HIIIIIIIIIII");
    int i = resources.length;
    while (i > 0) {
        staxHeaderDataReader.setResource(resources[i - 1]);
        i--;
    }
    return staxHeaderDataReader;

}

此资源应具有由TaskletStep复制的文件,但是在应用程序启动期间批处理失败。注意-这只是实际情况的一个虚假提示。

堆栈跟踪- main] o.s.b.c.l.support.SimpleJobLauncher:作业:[SimpleJob:[name = job]]启动,并带有以下参数:[{run.id = 10}] 2018-10-19 20:35:43.959 INFO 3108 --- [main] o.s.batch.core.job.SimpleStepHandler:执行步骤:[step1] 2018-10-19 20:35:43.998信息3108--[main] o.s.batch.core.job.SimpleStepHandler:执行步骤:[step2] 2018-10-19 20:35:44.009错误3108 --- [main] o.s.batch.core.step.AbstractStep:在作业作业中执行步骤step2时遇到错误

java.lang.IllegalArgumentException:必须设置资源     在org.springframework.util.Assert.notNull(Assert.java:193)〜[spring-core-5.0.8.RELEASE.jar:5.0.8.RELEASE]     在org.springframework.batch.item.file.MultiResourceItemReader.open(MultiResourceItemReader.java:168)〜[spring-batch-infrastructure-4.0.1.RELEASE.jar:4.0.1.RELEASE]     在org.springframework.batch.item.support.CompositeItemStream.open(CompositeItemStream.java:103)〜[spring-batch-infrastructure-4.0.1.RELEASE.jar:4.0.1.RELEASE]     在org.springframework.batch.core.step.tasklet.TaskletStep.open(TaskletStep.java:310)〜[spring-batch-core-4.0.1.RELEASE.jar:4.0.1.RELEASE]     在org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:197)〜[spring-batch-core-4.0.1.RELEASE.jar:4.0.1.RELEASE]     在org.springframework.batch.core.job.SimpleStepHandler.handleStep(SimpleStepHandler.java:148)[spring-batch-core-4.0.1.RELEASE.jar:4.0.1.RELEASE]     在org.springframework.batch.core.job.AbstractJob.handleStep(AbstractJob.java:394)上[spring-batch-core-4.0.1.RELEASE.jar:4.0.1.RELEASE]     在org.springframework.batch.core.job.SimpleJob.doExecute(SimpleJob.java:135)[spring-batch-core-4.0.1.RELEASE.jar:4.0.1.RELEASE]     在org.springframework.batch.core.job.AbstractJob.execute(AbstractJob.java:308)上[spring-batch-core-4.0.1.RELEASE.jar:4.0.1.RELEASE]     在org.springframework.batch.core.launch.support.SimpleJobLauncher $ 1.run(SimpleJobLauncher.java:141)[spring-batch-core-4.0.1.RELEASE.jar:4.0.1.RELEASE]     在org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:50)[spring-core-5.0.8.RELEASE.jar:5.0.8.RELEASE]     在org.springframework.batch.core.launch.support.SimpleJobLauncher.run(SimpleJobLauncher.java:134)[spring-batch-core-4.0.1.RELEASE.jar:4.0.1.RELEASE]     在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)〜[na:1.8.0_181]     在sun.reflect.NativeMethodAccessorImpl.invoke(未知来源)〜[na:1.8.0_181]     在sun.reflect.DelegatingMethodAccessorImpl.invoke(未知来源)〜[na:1.8.0_181]     在java.lang.reflect.Method.invoke(未知来源)〜[na:1.8.0_181]     在org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:343)[spring-aop-5.0.8.RELEASE.jar:5.0.8.RELEASE]     在org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:197)[spring-aop-5.0.8.RELEASE.jar:5.0.8.RELEASE]     在org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)[spring-aop-5.0.8.RELEASE.jar:5.0.8.RELEASE]     在org.springframework.batch.core.configuration.annotation.SimpleBatchConfiguration $ PassthruAdvice.invoke(SimpleBatchConfiguration.java:127)[spring-batch-core-4.0.1.RELEASE.jar:4.0.1.RELEASE]     在org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)[spring-aop-5.0.8.RELEASE.jar:5.0.8.RELEASE]     在org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)[spring-aop-5.0.8.RELEASE.jar:5.0.8.RELEASE]     在com.sun.proxy。$ Proxy89.run(未知来源)[na:na]     在org.springframework.boot.autoconfigure.batch.JobLauncherCommandLineRunner.execute(JobLauncherCommandLineRunner.java:163)上[spring-boot-autoconfigure-2.0.4.RELEASE.jar:2.0.4.RELEASE]     在org.springframework.boot.autoconfigure.batch.JobLauncherCommandLineRunner.executeLocalJobs(JobLauncherCommandLineRunner.java:179)上[spring-boot-autoconfigure-2.0.4.RELEASE.jar:2.0.4.RELEASE]     在org.springframework.boot.autoconfigure.batch.JobLauncherCommandLineRunner.launchJobFromProperties(JobLauncherCommandLineRunner.java:134)[spring-boot-autoconfigure-2.0.4.RELEASE.jar:2.0.4.RELEASE]     在org.springframework.boot.autoconfigure.batch.JobLauncherCommandLineRunner.run(JobLauncherCommandLineRunner.java:128)上[spring-boot-autoconfigure-2.0.4.RELEASE.jar:2.0.4.RELEASE]     在org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:800)上[spring-boot-2.0.4.RELEASE.jar:2.0.4.RELEASE]     在org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:784)上[spring-boot-2.0.4.RELEASE.jar:2.0.4.RELEASE]     在org.springframework.boot.SpringApplication.run(SpringApplication.java:338)上[spring-boot-2.0.4.RELEASE.jar:2.0.4.RELEASE]     在org.springframework.boot.SpringApplication.run(SpringApplication.java:1258)上[spring-boot-2.0.4.RELEASE.jar:2.0.4.RELEASE]     在org.springframework.boot.SpringApplication.run(SpringApplication.java:1246)上[spring-boot-2.0.4.RELEASE.jar:2.0.4.RELEASE]     在com.infotech.batch.SpringBootBatchTaskletApplication.main(SpringBootBatchTaskletApplication.java:12)[classes /:na]

2018-10-19 20:35:44.014错误3108 --- [main] o.s.batch.core.step.AbstractStep:在作业job中的步骤step2中关闭步骤执行资源时发生异常

java.lang.NullPointerException:空     在org.springframework.batch.item.file.MultiResourceItemReader.close(MultiResourceItemReader.java:155)〜[spring-batch-infrastructure-4.0.1.RELEASE.jar:4.0.1.RELEASE]     在org.springframework.batch.item.support.CompositeItemStream.close(CompositeItemStream.java:89)〜[spring-batch-infrastructure-4.0.1.RELEASE.jar:4.0.1.RELEASE]     在org.springframework.batch.core.step.tasklet.TaskletStep.close(TaskletStep.java:305)〜[spring-batch-core-4.0.1.RELEASE.jar:4.0.1.RELEASE]     在org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:271)〜[spring-batch-core-4.0.1.RELEASE.jar:4.0.1.RELEASE]     在org.springframework.batch.core.job.SimpleStepHandler.handleStep(SimpleStepHandler.java:148)[spring-batch-core-4.0.1.RELEASE.jar:4.0.1.RELEASE]     在org.springframework.batch.core.job.AbstractJob.handleStep(AbstractJob.java:394)上[spring-batch-core-4.0.1.RELEASE.jar:4.0.1.RELEASE]     在org.springframework.batch.core.job.SimpleJob.doExecute(SimpleJob.java:135)[spring-batch-core-4.0.1.RELEASE.jar:4.0.1.RELEASE]     在org.springframework.batch.core.job.AbstractJob.execute(AbstractJob.java:308)上[spring-batch-core-4.0.1.RELEASE.jar:4.0.1.RELEASE]     在org.springframework.batch.core.launch.support.SimpleJobLauncher $ 1.run(SimpleJobLauncher.java:141)[spring-batch-core-4.0.1.RELEASE.jar:4.0.1.RELEASE]     在org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:50)[spring-core-5.0.8.RELEASE.jar:5.0.8.RELEASE]     在org.springframework.batch.core.launch.support.SimpleJobLauncher.run(SimpleJobLauncher.java:134)[spring-batch-core-4.0.1.RELEASE.jar:4.0.1.RELEASE]     在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)〜[na:1.8.0_181]     在sun.reflect.NativeMethodAccessorImpl.invoke(未知来源)〜[na:1.8.0_181]     在sun.reflect.DelegatingMethodAccessorImpl.invoke(未知来源)〜[na:1.8.0_181]     在java.lang.reflect.Method.invoke(未知来源)〜[na:1.8.0_181]     在org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:343)[spring-aop-5.0.8.RELEASE.jar:5.0.8.RELEASE]     在org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:197)[spring-aop-5.0.8.RELEASE.jar:5.0.8.RELEASE]     在org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)[spring-aop-5.0.8.RELEASE.jar:5.0.8.RELEASE]     在org.springframework.batch.core.configuration.annotation.SimpleBatchConfiguration $ PassthruAdvice.invoke(SimpleBatchConfiguration.java:127)[spring-batch-core-4.0.1.RELEASE.jar:4.0.1.RELEASE]     在org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)[spring-aop-5.0.8.RELEASE.jar:5.0.8.RELEASE]     在org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)[spring-aop-5.0.8.RELEASE.jar:5.0.8.RELEASE]     在com.sun.proxy。$ Proxy89.run(未知来源)[na:na]     在org.springframework.boot.autoconfigure.batch.JobLauncherCommandLineRunner.execute(JobLauncherCommandLineRunner.java:163)上[spring-boot-autoconfigure-2.0.4.RELEASE.jar:2.0.4.RELEASE]     在org.springframework.boot.autoconfigure.batch.JobLauncherCommandLineRunner.executeLocalJobs(JobLauncherCommandLineRunner.java:179)上[spring-boot-autoconfigure-2.0.4.RELEASE.jar:2.0.4.RELEASE]     在org.springframework.boot.autoconfigure.batch.JobLauncherCommandLineRunner.launchJobFromProperties(JobLauncherCommandLineRunner.java:134)[spring-boot-autoconfigure-2.0.4.RELEASE.jar:2.0.4.RELEASE]     在org.springframework.boot.autoconfigure.batch.JobLauncherCommandLineRunner.run(JobLauncherCommandLineRunner.java:128)上[spring-boot-autoconfigure-2.0.4.RELEASE.jar:2.0.4.RELEASE]     在org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:800)上[spring-boot-2.0.4.RELEASE.jar:2.0.4.RELEASE]     在org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:784)上[spring-boot-2.0.4.RELEASE.jar:2.0.4.RELEASE]     在org.springframework.boot.SpringApplication.run(SpringApplication.java:338)上[spring-boot-2.0.4.RELEASE.jar:2.0.4.RELEASE]     在org.springframework.boot.SpringApplication.run(SpringApplication.java:1258)上[spring-boot-2.0.4.RELEASE.jar:2.0.4.RELEASE]     在org.springframework.boot.SpringApplication.run(SpringApplication.java:1246)上[spring-boot-2.0.4.RELEASE.jar:2.0.4.RELEASE]     在com.infotech.batch.SpringBootBatchTaskletApplication.main(SpringBootBatchTaskletApplication.java:12)[classes /:na]

2018-10-19 20:35:44.019信息3108 --- [main] osbclsupport.SimpleJobLauncher:Job:[SimpleJob:[name = job]]使用以下参数完成:[{run.id = 10 }]以及以下状态:[FAILED]

1 个答案:

答案 0 :(得分:0)

您无需在此处的委托阅读器上手动设置资源:

private StaxEventItemReader<String> headerXmlReader()
    throws FileNotFoundException, XMLStreamException, URISyntaxException {
   // TODO Auto-generated method stub

   StaxEventItemReader<String> staxHeaderDataReader = new StaxEventItemReader<String>();

   int i = resources.length;
   while (i > 0) {
       staxHeaderDataReader.setResource(resources[i - 1]);
       i--;
   }
   return staxHeaderDataReader;

}

MultiResourceItemReaderdo it automatically读取资源。基本上,您需要做的是配置代理上除资源之外的所有内容(根标记名,解组器等)。资源将由委托上的MultiResourceItemReader动态设置。

您可以找到有关如何使用委托人MultiResourceItemReader here配置StaxEventItemReader的示例。

  

将步骤1的资源值传递给下一步

step1应该通过步骤执行上下文将有关创建的资源的信息动态传递给step2。有关如何执行此操作的更多详细信息,请参阅:

希望这会有所帮助。