我正在使用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
答案 0 :(得分:1)
您可以创建一个新线程,但是最好的解决方案是创建ThreadPoolExecutor来管理线程,或者Scheduled注释也可以帮助我们。
new Thread() {
@Override
public void run() {
service.cleanup(id);
}
}.start();
已更新
最佳答案是将 Stack 与 Thread 结合使用。 这是我已经完成的解决方案。
答案 1 :(得分:0)
我最终使用了HandlerInterceptorAdapter
,afterCompletion
是我需要的回调。我要处理的唯一挑战是传递资源的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。