内容:
我有一个用于下载zip存档的端点。
@GetMapping public DeferredResult<StreamingResponseBody> download(/**params**/) { }
由于文件数量和文件大小的原因,无法将它们全部保存在内存中(即,我必须从外部服务读取大块文件,将它们存储到临时目录中,创建一个zip存档,将大块文件写入zip,请在归档后删除所有临时文件- 此时,我只剩下磁盘上的归档文件 -然后将zip流回客户端。
我已经设法实现了该功能,但是我不确定哪种方法是在请求后进行清理的最佳方法(请注意,该服务由多个客户端使用-因此应该可以同时进行多个下载)。
目前,我使用HandlerInterceptor的preHandle方法会为方法中的存档生成一个随机名称,并将其作为请求属性传递。request属性将传递给生成档案的服务,并用作档案名称。然后,在afterCompletion拦截器的方法中,我从request属性中读取档案名称并删除档案。
HandlerInterceptor
preHandle
afterCompletion
class ZipInterceptor implements HandlerInterceptor { public static final String ZIP_ATTRIBUTE_NAME = "zipName"; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { if(isApplicable(request)){ request.setAttribute(ZIP_ATTRIBUTE_NAME, generateZipName()); } return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { if(isApplicable(request)){ deleteZip((String)request.getAttribute(ZIP_ATTRIBUTE_NAME)); } } }
我考虑过的另一种方法:
您认为哪种方法是应对这种情况的最佳方法?
正如JB Nizet在评论中指出的那样,最好的方法是 根本不将文件存储在磁盘上 。
如果在请求返回到客户端之后,您的特定上下文在磁盘上留下文件,则可以使用下一种方法来删除它们。
class CleanupInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { // do cleanup here } }
如果有人找到解决此问题的更优雅的解决方案,请在此处发布您的答案。