【问题标题】:How to access jobparameter from ItemReader class of Spring batch job in spring boot web application如何从 Spring Boot Web 应用程序中 Spring 批处理作业的 ItemReader 类访问作业参数
【发布时间】:2016-03-04 06:21:28
【问题描述】:

我正在从我的控制器启动一个春季批处理作业。我需要通过基于 java 的配置从配置的自定义ItemReader 访问作业参数fileName。但我总是从我的 ItemReader 获取文件名为 null。请帮忙。 我之所以这样启动,是因为我必须根据用户请求更改 ItemReader 文件。

我的控制器:

@RestController
@RequestMapping(value = "/")
public class SimpleController {


@Autowired
Step step;

@Autowired
private JobBuilderFactory jobs;

@Autowired
private StepBuilderFactory steps;

@Autowired
private JobRepository jobRepository;

@Autowired
JobLauncher jobLauncher;

@RequestMapping(method = RequestMethod.GET)
public void StartJob() throws JobParametersInvalidException, JobExecutionAlreadyRunningException, JobRestartException, JobInstanceAlreadyCompleteException {
    JobParameter param = new JobParameter("ValueBeingSetFromRequestHeader");
    HashMap map = new HashMap<String, JobParameter>();
    map.put("fileName",param);
    SimpleJob job = new SimpleJob("test");
    job.addStep(step);
    System.out.println(jobRepository);
    job.setJobRepository(jobRepository);

    System.out.println( jobRepository.getLastJobExecution(job.getName(), new JobParameters(map)));

    jobLauncher.run(job, new JobParameters(map));

}

}

而我的 Job 步骤配置类是

public class ProducerBatchJobConfigurer {


private String fileName;

public String getFileName() {
    return fileName;
}
@Value("#{jobParameters['fileName']}")
public void setFileName(String fileName) {
    this.fileName = fileName;
}

@Bean
public ItemReader reader() {
    System.out.println(fileName);
    if (fileName == null)
        return new DummyReader();
    FlatFileItemReader faltFileReader =  new FlatFileItemReader();

    faltFileReader.setResource(new FileSystemResource(new File(fileName)));
    faltFileReader.setResource(new FileSystemResource(new File(fileName)));
    DefaultLineMapper<KafkaMessage> lineMapper = new DefaultLineMapper<KafkaMessage>();
    lineMapper.setLineTokenizer(new DelimitedLineTokenizer());
    lineMapper.setFieldSetMapper(new CSVFieldMapper());
    faltFileReader.setLineMapper(lineMapper);
    return faltFileReader;
}

@Bean
public ItemProcessor processor() {
   return new CustomItemProcessor();

}

@Bean
public ItemWriter writer() {
    return new KafkaWriter();
}



@Bean
public Step step1(StepBuilderFactory stepBuilderFactory,
                  ItemReader reader, ItemWriter writer,
                  ItemProcessor processor) {
    System.out.println("ddddddddddddddd");
    return stepBuilderFactory.get("step1")
            .chunk(10).reader(reader)
            .processor(processor).writer(writer).build();
}
@Bean
public StepScope stepScope() {
    final StepScope stepScope = new StepScope();
    stepScope.setAutoProxy(true);
    return stepScope;
}
@Bean
public JobScope jobScope(){
    return new JobScope();
}
}

【问题讨论】:

  • ProducerBatchJobConfigurer 本身不是一个 bean,我会在 ItemReader Beandefinition 阅读器上使用@value(@Value ....)
  • 非常感谢迈克尔。现在随着您的更改文件名被填充。但无法运行作业。步骤失败并出现以下错误。 org.springframework.batch.item.ReaderNotOpenException: Reader must be open before it can be read. at org.springframework.batch.item.file.FlatFileItemReader.readLine(FlatFileItemReader.java:195) ~[spring-batch-infrastructure-3.0.6.RELEASE.jar:3.0.6.RELEASE]
  • 我不得不将@Scope("job") 也放在阅读器之上,否则它会给出错误Property or field 'jobParameters' cannot be found 但不幸的是无法运行该作业。步骤失败并出现以下错误。 org.springframework.batch.item.ReaderNotOpenException: Reader must be open before it can be read. at org.springframework.batch.item.file.FlatFileItemReader.readLine(FlatFileItemReader.java:195) ~[spring-batch-infrastructure-3.0.6.RELEASE.jar:3.0.6.RELEASE]
  • 请尝试使用 ItemStreamReader 或具体的 FlatFileItemReader 作为 Beantype,请参阅 stackoverflow.com/questions/23847661/…,如果可行,您或我可以将其作为解决方案发布
  • @MichaelPralow:谢谢。这是工作。请继续并将其作为解决方案发布。如果可能,请多解释一下。 :)

标签: java spring-boot spring-batch


【解决方案1】:
@Bean
public ItemReader reader() {
 ...
}

应该改为

@Bean
public ItemStreamReader reader() {
 ...
}

甚至更具体

@Bean
public FlatFileItemReader reader() {
 ...
}

步骤定义也应更改为

@Bean
public Step step1(StepBuilderFactory stepBuilderFactory,
                  ItemStreamReader reader, ItemWriter writer,
                  ItemProcessor processor) {

}

为什么需要这样做?

如果 itemReader 实现了ItemStream 接口(或ItemStreamReader),Spring 会这样对待它。

https://docs.spring.io/spring-batch/reference/html/readersAndWriters.html#delegatePatternAndRegistering

直接连接到 Step 的读取器、写入器或处理器 如果它实现 ItemStream 或 StepListener 接口。

这意味着 spring 将调用 open、update 和 close 方法

Spring Batch: org.springframework.batch.item.ReaderNotOpenException: Reader must be open before it can be read的类似问题

【讨论】:

    【解决方案2】:

    使用@Value("#{jobParameters[fileName]}") 而不是@Value("#{jobParameters['fileName']}")

    【讨论】:

    • 感谢您的回复。我试过上面的。但不工作。 :(
    猜你喜欢
    • 2019-11-14
    • 1970-01-01
    • 1970-01-01
    • 2020-08-29
    • 2014-06-20
    • 1970-01-01
    • 2014-09-27
    • 2013-06-14
    • 1970-01-01
    相关资源
    最近更新 更多