【问题标题】:Unable to Read REST Parameters in Tasklet / ItemReader无法读取 Tasklet / ItemReader 中的 REST 参数
【发布时间】:2020-04-09 01:40:20
【问题描述】:

我想设置一个新的批处理作业。

这个 Job 应该从 Rest 接口接收一些参数(我正在使用 @EnableBatchProcessing 进行自动化 JobScanning)。

我只希望每次休息调用都执行一次工作 -> 这就是为什么我认为 tasklet 将是首选武器。但是我没有让@StepScope 只使用一个 tasklet 作业(似乎没有没有块的 StepScope 可用,但如果我错了,请纠正我)...

我的另一个想法是创建一个 ItemReader,它读取 JobParameters 并创建单个域对象(从参数),然后处理数据并写入 Dummy ItemWriter。

我尝试这样设置 ItemReader:

@Bean
@StepScope
public ItemReader<BatchPrinterJob> setupParameterItemReader(
        @Value("#{jobParameters}") Map<String, Object> jobParameters) {

    ItemReader<BatchPrinterJob> reader = new ItemReader<BatchPrinterJob>() {

        @Override
        public BatchPrinterJob read()
                throws Exception, UnexpectedInputException, ParseException, NonTransientResourceException {

            BatchPrinterJob job = new BatchPrinterJob();
            LOG.info(jobParameters.toString());
            return job;
        }
    };
    return reader;
}

我尝试使用这样的 POST 请求开始作业:myhost:8080/jobs/thisjobsname?name=testname

但唯一被记录的是 run.id。

【问题讨论】:

    标签: java rest parameters spring-batch


    【解决方案1】:

    好的,我根据你的例子为这个工作写了我自己的启动器:

    @RestController
    public class AutoPrintLaunchingController {
    
    @Autowired
    private JobLauncher jobLauncher;
    
    @Autowired
    private AutoPrint autoprint;
    
    @RequestMapping(value = "/jobs/AutoPrint", method = RequestMethod.POST)
    @ResponseStatus(HttpStatus.ACCEPTED)
    public void launch(@RequestParam("Drucker") String printer, @RequestParam("Fach") String fach,
            @RequestParam("Dokument") String doc, @RequestParam("DokumentParameter") String param) throws Exception {
    
        JobParametersBuilder jpb = new JobParametersBuilder();
        jpb.addString("Drucker", printer);
        jpb.addString("Fach", fach);
        jpb.addString("Dokument", doc);
        jpb.addString("DokumentParameter", param);
        jpb.addDate("dateInstant", Date.from(LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant()));
    
        JobParameters jobParameters = jpb.toJobParameters();
        this.jobLauncher.run(autoprint.createAutoPrintJob(), jobParameters);
    }
    
    }
    

    这是按要求工作的!

    【讨论】:

      【解决方案2】:

      我认为 tasklet 将是首选的武器。但是我没有让@StepScope 只使用一个 tasklet 作业(似乎没有没有块的 StepScope 可用,但如果我错了,请纠正我)...

      您可以在 tasklet 上使用@StepScope,这是一个示例:

      @Bean
      @StepScope
      public Tasklet tasklet(@Value("#{jobParameters['parameter']}") String parameter) {
          return (contribution, chunkContext) -> {
              // use job parameter here
              return RepeatStatus.FINISHED;
          };
      }
      

      然后使用tasklet创建步骤:

      @Bean
      public Step step() {
          return this.stepBuilderFactory.get("step")
                  .tasklet(tasklet(null))
                  .build();
      }
      

      【讨论】:

      • 感谢代码编译,但参数未计算为 Rest 参数:我尝试记录输出但它总是计算为 null:@Bean @StepScope public Tasklet tasklet(@Value("#{jobParameters['parameter']}") String parameter) { return (contribution, chunkContext) -&gt; { LOG.info(chunkContext.getStepContext().getJobParameters().toString()); LOG.info("customParameter: " + parameter); return RepeatStatus.FINISHED; }; } 这仅记录更改的 run.id + customParameter :空
      • 在你的休息控制器中,你是否将请求参数作为作业参数传递?此答案显示了一个示例,您需要确保您尝试在 tasklet 中获取的作业参数正确地从您的控制器传递给作业。
      • 我想这可能是问题所在。我们使用 AutomaticJobRegistrarConfiguration 自动扫描作业并为它们创建端点。有没有办法用一个 Job 所需的参数手动覆盖端点?或者我可以以某种方式告诉 AutomaticJobRegistrar 扫描请求的参数吗?
      • 这与作业如何注册无关,而与作业如何启动有关。我的意思是您的控制器应该确保使用您在 tasklet 中需要的参数启动作业。这是一个例子:github.com/mminella/LearningSpringBatch/blob/master/src/…
      猜你喜欢
      • 2021-02-12
      • 1970-01-01
      • 1970-01-01
      • 2013-06-19
      • 2019-02-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-06
      相关资源
      最近更新 更多