客户端收到资源后的Spring Boot回调?

时间:2018-10-28 23:30:33

标签: spring-boot

我正在使用Spring Boot创建一个端点,该端点执行系统命令(java.lang.Runtime API)的组合以生成一个zip文件,并根据请求返回到客户端,这是代码。

    @GetMapping(value = "generateZipFile")
    public ResponseEntity<Resource> generateZipFile(@RequestParam("id") Integer id) throws IOException {
        org.springframework.core.io.Resource resource = null;
        //generate mysterious zip file using commandline (java.lang.Runtime API) 
        resource = service.generateTmpResource(id);
        return ResponseEntity.ok()
                    .header(HttpHeaders.CONTENT_TYPE, "application/zip")
                    .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"randomFile.zip\"")
                    .body(resource);
        //somehow delete generated file here after client receives it 
    }

由于明显的磁盘限制原因,我无法继续在服务器上堆积文件,因此,我正在寻找一种方法,以便客户端下载文件后立即将其删除。 Spring Boot中是否有解决方案?我基本上需要钩住一个回调,该回调将在用户收到资源后进行清理。

我正在使用Spring Boot 2.0.6

2 个答案:

答案 0 :(得分:1)

您可以创建一个新线程,但是最好的解决方案是创建ThreadPoolExecutor来管理线程,或者Scheduled注释也可以帮助我们。

new Thread() {
    @Override
    public void run() {
        service.cleanup(id);
    }
}.start();

已更新

最佳答案是将 Stack Thread 结合使用。 这是我已经完成的解决方案。

https://github.com/jjohxx/example-thread

答案 1 :(得分:0)

我最终使用了HandlerInterceptorAdapterafterCompletion是我需要的回调。我要处理的唯一挑战是传递资源的ID进行清理,这是通过在控制器方法中添加标头来解决的:

@GetMapping(value = "generateZipFile")
public ResponseEntity<Resource> genereateZipFile(@RequestParam("id") Integer id,
                                                 RedirectAttributes redirectAttributes) throws IOException {
    org.springframework.core.io.Resource resource = myService.generateTmpResource(id);;
    return ResponseEntity.ok()
            .header(HttpHeaders.CONTENT_TYPE, "application/zip")
            .header(MyInterceptor.TMP_RESOURCE_ID_HEADER, id.toString())
            .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"someFile.zip\"")
            .body(resource);

}

拦截器代码:

@Component
public class MyInterceptor extends HandlerInterceptorAdapter {

    public static final String TMP_RESOURCE_ID_HEADER = "Tmp-ID";

    @Autowired
    private MyService myService;

    @Override
    public void afterCompletion(HttpServletRequest request,
                                HttpServletResponse response,
                                Object handler,
                                Exception ex) {
        if(response == null || !response.containsHeader(TMP_RESOURCE_ID_HEADER)) return;
        String tmpFileId = response.getHeader(TMP_RESOURCE_ID_HEADER);
        myService.cleanup(tmpFileId);
    }
}

有关拦截器的更多信息,请参见here