Отправленный ответ после завершения Spring Batch Работа в Spring Boot - PullRequest
0 голосов
/ 28 сентября 2018

Мне нужно загрузить CSV, преобразовать его в Java Object и затем сохранить в базе данных.Я использую Spring Boot с Spring Batch для достижения этой цели.Я прошел несколько уроков.После их анализа кажется, что Spring Batch Job выполняется асинхронно как ответ, отправленный клиенту до завершения задания.Но мне нужно отправить ответ клиенту после выполнения задания.Возможно ли это сделать?Пожалуйста, помогите решить эту проблему.Спасибо, мой код контроллера выглядит следующим образом:

@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();
    }

}

1 Ответ

0 голосов
/ 01 октября 2018

кажется, что Spring Batch Job выполняется асинхронно как ответ, отправленный клиенту до завершения задания

Это верно, если средство запуска задания настроено с асинхронным исполнителем задания.Если в средстве запуска заданий используется синхронный исполнитель заданий (по умолчанию), задание будет выполняться до завершения.Но в этом случае веб-клиент будет ждать, пока работа не будет завершена, что, вероятно, и не требуется (подробности здесь: https://docs.spring.io/spring-batch/4.0.x/reference/html/job.html#runningJobsFromWebContainer).

Мне нужно отправить ответ наклиент после выполнения задания

Если время выполнения вашего задания достаточно быстро, чтобы быть приемлемым в качестве времени выполнения для веб-запроса, вы можете использовать (по умолчанию) синхронный исполнитель задач. В этом случаеВы можете отправить ответ после завершения задания. Но, как уже было сказано, это не рекомендуется для длительных заданий, так как запрос http может прерваться до завершения задания.

Попытка использовать org.springframework.web.context.request.async.DeferredResult (илиПодобный подход) был бы уродливым хаком, поскольку он не решает проблему. Поэтому я не вижу приемлемого варианта для вашего варианта использования.

...