Java 将响应返回给客户端后进行清理

Java 将响应返回给客户端后进行清理,java,spring,spring-boot,Java,Spring,Spring Boot,上下文: 我有一个用于下载zip存档的端点 @GetMapping public DeferredResult<StreamingResponseBody> download(/**params**/) { } 我考虑过的另一种方法: 将存档名称返回给客户端(作为标题或下载文件的名称),并依靠客户端调用新端点来删除存档。主要的缺点是,我无法强制客户机使用此协议(最终可能导致磁盘已满) 每小时(或另一个时间间隔)运行一次作业,并清理旧档案。缺点是,我不确定文件是否已流回到客户端(

上下文:

我有一个用于下载zip存档的端点

@GetMapping
public DeferredResult<StreamingResponseBody> download(/**params**/) {

}
我考虑过的另一种方法:

  • 将存档名称返回给客户端(作为标题或下载文件的名称),并依靠客户端调用新端点来删除存档。主要的缺点是,我无法强制客户机使用此协议(最终可能导致磁盘已满)
  • 每小时(或另一个时间间隔)运行一次作业,并清理旧档案。缺点是,我不确定文件是否已流回到客户端(因此,对于足够大的文件,任何时间间隔都会删除尚未流完的文件)

在您看来,哪种方法是处理这种情况的最佳方法?

正如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
    }
}

如果有人找到了更优雅的解决方案,请在这里发布您的答案。

我也有类似的情况。我认为最安全的方法是创建一个后台作业来清理文件。我在创建的文件名中添加了一个时间戳。然后后台作业将筛选出比当前时间至少早30分钟的文件并将其删除。这样我就可以确定这些文件已经完成流式处理,可以安全地删除

为什么首先要将归档文件(和文件)存储在磁盘上?您只需将响应输出流包装成ZipOutputStream,并将zip直接写入响应即可。谢谢您的回答@ZB Nizet。这是一种可以重构它并避免问题的方法。我将使用您的解决方案,避免在磁盘上创建zip(正如您所指出的,这不会增加任何价值),但由于一些限制,我仍然必须将文件写入磁盘。在这种情况下,我没有一个zip,而是一个要清理的文件目录。您知道我有什么方法可以实现这一点吗(这与最初定义的场景相同,使用目录而不是zip存档)。
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
    }
}