Как создать частично асинхронный пост-запрос в Spring boot? - PullRequest
1 голос
/ 12 мая 2019

Я новичок в Spring Boot и хотел бы создать своего рода асинхронный запрос. Это должно позволить пользователю загружать файл. Затем приложение Spring должно сохранить его и ответить пользователю, что файл был сохранен правильно.

Тогда происходит вся асинхронная часть. Сервер должен начать обработку файла (в фоновом режиме) сразу после его сохранения. В настоящее время он не работает в фоновом режиме (пользователь должен дождаться окончания обработки processFileInBackground):

Контроллер:

@CrossOrigin
@RestController
public class ProcessFileController {
    @Autowired
    ProcessFileService processFileService;

    @CrossOrigin
    @PostMapping("/files/upload")
    public ResponseEntity<String> singleFileUpload(@RequestParam("file") MultipartFile file) {
        System.out.println("singleFileUpload tid: " + Thread.currentThread().getId());
        bytes = file.getBytes();
        // Save file...
        String plainText = new String(bytes, StandardCharsets.UTF_8);
        processFileInBackground(plainText);
        return new ResponseEntity<>("File successfully uploaded!", HttpStatus.OK);
    }


    private void processFileInBackground(String plainText) {
        processFileService = new ProcessFileService(plainText);
        String result = processFileService.getResult();
    }
}

Услуги:

@Service
public class ProcessFileService {

    private FileProcessor fileProcessor;

    public CompilerApiService(String plainText){
        fileProcessor = new FileProcessor(code);
    }

    @Async
    public String getResult(){
        System.out.println("getResult tid: " + Thread.currentThread().getId());
        // The call below takes a long time to finish
       return fileProcessor.getResult();
    }

}

Конфигурация:

@EnableAsync
@Configuration
public class AsyncConfig {
    @Bean
    public Executor threadPoolTaskExecutor() {
        return new ConcurrentTaskExecutor(Executors.newCachedThreadPool());
    }
}

1 Ответ

3 голосов
/ 12 мая 2019

Spring предлагает вам @ Async аннотацию, вам нужно отделить вашу асинхронную логику в отдельном классе и аннотировать ваш метод с помощью этой асинхронной работы, это выполнит вашу логику в отдельном потоке.Проверьте это https://spring.io/guides/gs/async-method/

Имейте в виду, что для выполнения в асинхронном режиме необходимо вызвать асинхронный метод извне класса вызывающего, что-то вроде этого

@CrossOrigin
@RestController
public class ProcessFileController {
    @Autowired
    ProcessFileService processFileService;

    @CrossOrigin
    @PostMapping("/files/upload")
    public ResponseEntity<String> singleFileUpload(@RequestParam("file") MultipartFile file) {
        bytes = file.getBytes();
        // Save file...
        String plainText = new String(bytes, StandardCharsets.UTF_8);
        processFileInBackground(plainText);
        return new ResponseEntity<>("File successfully uploaded!", HttpStatus.OK);
    }


    private void processFileInBackground(String plainText) {
        processFileService = new ProcessFileService(plainText);
        String result = processFileService.getResult();
    }
}

Служба

@Service
public class ProcessFileService {

    private FileProcessor fileProcessor;

    public CompilerApiService(String plainText){
        fileProcessor = new FileProcessor(code);
    }

    @Async
    public String getResult(){
       return fileProcessor.getResult();
    }

}

Конфигурация

@EnableAsync
@Configuration
public class AsyncConfig {
    @Bean(name = "threadPoolExecutor")
    public Executor getAsyncExecutor() {
      ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
      executor.setCorePoolSize(7);
      executor.setMaxPoolSize(42);
      executor.setQueueCapacity(11);
      executor.setThreadNamePrefix("threadPoolExecutor-");
      executor.initialize();
      return executor;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...