Java Spring批处理在Spring引导中完成作业后发送响应

Java Spring批处理在Spring引导中完成作业后发送响应,java,spring-boot,asynchronous,spring-batch,batch-processing,Java,Spring Boot,Asynchronous,Spring Batch,Batch Processing,我必须上传CSV,将其转换为Java对象,然后保存在数据库中。我使用SpringBoot和SpringBatch来实现这一点。我已经看过多个教程。在分析了这些之后,Spring批处理作业似乎以异步方式运行,作为在作业完成之前发送给客户机的响应。但我需要在作业执行完成后向客户端发送响应。有可能吗?请帮助解决此问题。谢谢,我的控制器代码如下: @RestController public class AppRestCtrl { Logger logger = LoggerFactory.g

我必须上传CSV,将其转换为Java对象,然后保存在数据库中。我使用SpringBoot和SpringBatch来实现这一点。我已经看过多个教程。在分析了这些之后,Spring批处理作业似乎以异步方式运行,作为在作业完成之前发送给客户机的响应。但我需要在作业执行完成后向客户端发送响应。有可能吗?请帮助解决此问题。谢谢,我的控制器代码如下:

@RestController
public class AppRestCtrl {

    Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    JobLauncher jobLauncher;

    @Autowired
    Job job;

    @PostMapping("/processFile")
    public ResponseEntity convertCsvToObject(@RequestParam("fileData") MultipartFile file) throws Exception {

        final Path rootLocation = Paths.get("uploads");

        if(!Files.exists(rootLocation)) {
            Files.createDirectories(rootLocation);
        }

        if(file.isEmpty()) {
            return ResponseEntity.badRequest().body("Empty File Not Allowed");
        }

        if(!file.getOriginalFilename().contains(".csv")) {
            return ResponseEntity.badRequest().body("File is Invalid!");
        }

        Files.deleteIfExists(rootLocation.resolve(file.getOriginalFilename()));
        Files.copy(file.getInputStream(), rootLocation.resolve(file.getOriginalFilename()));

        try {
            JobParameters jobParameters = new JobParametersBuilder().addLong("time", System.currentTimeMillis())
                    .toJobParameters();
            jobLauncher.run(job, jobParameters);
        } catch (Exception e) {
            logger.info(e.getMessage());

        return ResponseEntity.ok("Batch Process Started Successfully!");
    }

}
批处理配置文件:

@Configuration
public class BatchConfig {

    @Autowired
    public JobBuilderFactory jobBuilderFactory;

    @Autowired
    public StepBuilderFactory stepBuilderFactory;

    @Bean
    public Job job() {
        return jobBuilderFactory.get("job").incrementer(new RunIdIncrementer()).listener(new Listener())
                .flow(step1()).end().build();
    }

    @Bean
    public Step step1() {
        return stepBuilderFactory.get("step1").<ObjectNode, JsonNode>chunk(1)
                .reader(Reader.reader("uploads\\students.csv"))
                .processor(new Processor()).writer(new Writer()).build();
    }

}
@配置
公共类BatchConfig{
@自动连线
公共建筑商建筑商工厂;
@自动连线
公共StepBuilderFactory StepBuilderFactory;
@豆子
公职{
返回jobBuilderFactory.get(“job”).incrementer(new RunIdIncrementer()).listener(new listener())
.flow(step1()).end().build();
}
@豆子
公共步骤第1步(){
返回stepBuilderFactory.get(“step1”).chunk(1)
.reader(reader.reader(“上传\\students.csv”))
.processor(新处理器()).writer(新编写器()).build();
}
}
Spring批处理作业似乎是在作业完成之前异步运行的,作为发送给客户端的响应

如果作业启动程序配置了异步任务执行器,则为真。如果作业启动器使用同步任务执行器(默认),则作业将一直执行到完成。但在这种情况下,web客户端将等待作业完成,这可能是您不希望发生的(更多详细信息,请参见此处)

我需要在作业执行完成后向客户发送响应

如果作业执行时间足够快,可以接受为web请求的执行时间,则可以使用(默认)同步任务执行器。在这种情况下,可以在作业完成后发送响应。但是如上所述,对于长时间运行的作业,不建议这样做,因为http请求可能在作业完成之前超时

尝试使用
org.springframework.web.context.request.async.DeferredResult
(或类似的方法)将是一个丑陋的黑客行为,因为它无法解决问题。因此,我认为您的用例没有可行的选择