休息服务下载文件并删除后

Rest service download file and delete it after that

提问人:Владимир Гичев 提问时间:11/17/2023 更新时间:11/19/2023 访问量:32

问:

我有下载文件的当前代码:

@GetMapping("/download/{fileName:.+}")
public ResponseEntity<Resource> downloadFile(@PathVariable String fileName) {
try {
    Path filePath = Paths.get(directoryPath).resolve(fileName);
    Resource resource = new UrlResource(filePath.toUri());
    if (resource.exists() && resource.isReadable()) {
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
    headers.setContentDispositionFormData("attachment", fileName);
    return ResponseEntity.ok().headers(headers).body(resource);
    } else {
    logger.error("File not found: " + fileName );
    return ResponseEntity.notFound().build();
    }
} catch (Exception e) {
    logger.error("Error while downloading file: " + fileName, e);
}
return ResponseEntity.notFound().build();
}

但是现在我需要实现逻辑来在某些情况下删除文件。我尝试创建对象并在那之后删除它,但该文件在完全下载之前就被删除了。客户端下载或停止文件后如何删除文件?Resource

Java Spring spring-boot 休息

评论


答:

0赞 David Weber 11/19/2023 #1

编辑:

解决方案是添加一个 Interceptor 和 .在删除文件所需的逻辑中实现了。afterCompletion()afterCompletion()

例:

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

}


The interceptor code:

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

从这里获取的解释:客户端收到资源后的Spring Boot回调?

旧(机器人是否正常工作):

您可以在 try catch 中添加一个子句,用于检查文件是否存在,如果存在,则删除该文件。finally

该子句在任何情况下都以保证的方式执行,并在 和 之后执行。finallytrycatch

@GetMapping("/download/{fileName:.+}")
public ResponseEntity<Resource> downloadFile(@PathVariable String fileName) {
try {
    ...
} catch (Exception e) {
    ...
} finally {
    ... delete the file here if it exists
}
    return ResponseEntity.notFound().build();
}

评论

0赞 Владимир Гичев 11/20/2023
这是行不通的。在完全下载之前,文件将被删除。
1赞 David Weber 11/20/2023
那么请检查一下:stackoverflow.com/questions/53036981/......
0赞 Владимир Гичев 11/20/2023
按照您给我的链接,我添加了 Interceptor 和 afterCompletion 方法。在afterComplete中,我添加了删除文件的逻辑,它就像一个魅力!谢谢!
0赞 David Weber 11/20/2023
不客气。我编辑了我的答案,以便其他开发人员也可以找到解决方案!