【问题标题】:How to create partly async post request in Spring boot?如何在 Spring Boot 中创建部分异步发布请求?
【发布时间】:2019-05-12 19:44:58
【问题描述】:

我是 Spring Boot 新手,我想创建一种异步请求。它应该允许用户上传文件。然后 Spring 应用程序应该保存它并回答用户该文件已正确保存。

然后整个异步部分发生。服务器应在保存文件后立即开始处理文件(在后台)。目前,它不在后台运行(用户需要等到processFileInBackgroundfinishes):

控制器:

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

【问题讨论】:

  • 您可以简单地创建一个线程来保存文件,然后您就可以开始处理了。
  • 查看@Async 注释,例如here
  • 我的建议是尝试在此处发布代码以便我们解决问题
  • @Deadpool 我在使用 Async 注解后发布了一些代码,但我仍然面临一些问题...

标签: java spring-boot http-post


【解决方案1】:

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;
    }
}

【讨论】:

  • 我尝试按照该指南进行操作,但它对我不起作用——我一定错过了什么。你能看一下代码吗?我编辑了问题
  • 将您的代码与我在更新答案中的编辑进行比较,这应该可以解决您的问题。
  • 不幸的是,它没有按我的预期工作。我向/files/upload 发出 POST 请求,文件需要 9 秒才能处理。我需要等待大约 9.2 秒才能收到该请求的 ResponseEntity。我在这里错过了什么吗?
  • 也许这是文件处理的实际时间,您可以通过在 getResult 方法中放置向您显示线程 ID 的语句来检查,放入 System.out.println(Thread.CurrentThread().getId ())
  • 我在 ProcessFileController.singleFileUpload()ProcessFileService.getResult() 方法中都放置了该声明。它们都打印相同的值 (26)。应该这样吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-07-06
相关资源
最近更新 更多