如何在 JAX-RS REST 服务响应后清理临时文件?

How to clean up temporary file after response in JAX-RS REST Service?

我正在从我的 JAX-RS REST 服务返回一个临时文件,如下所示:

@GET
@Produces(MediaType.APPLICATION_OCTET_STREAM)
public Response getFile() {
  File file = ... // create a temporary file
  return Response.ok(file, MediaType.APPLICATION_OCTET_STREAM)
      .header("Content-Disposition", "attachment; filename=\"" + file.getName() + "\"" ) //optional
      .build();
}

处理完响应后删除此临时文件的正确方法是什么? JAX-RS 实现(如 Jersey)是否应该自动执行此操作?

您可以传递 StreamingOutput 的实例,将源文件的内容复制到客户端输出并最终删除文件。

final Path path = getTheFile().toPath();
final StreamingOutput output = o -> {
    final long copied = Files.copy(path, o);
    final boolean deleted = Files.deleteIfExists(path);
};
return Response.ok(output).build();
final File file = getTheFile();
return Response.ok((StreamingOutput) output -> {
        final long copied = Files.copy(file.toPath(), output);
        final boolean deleted = file.delete();
    }).build();

https://dzone.com/articles/jax-rs-streaming-response 上的示例看起来比 Jin Kwon 的简短回复更有帮助。

这是一个例子:

public Response getDocumentForMachine(@PathParam("custno") String custno, @PathParam("machineno") String machineno,
        @PathParam("documentno") String documentno, @QueryParam("language") @DefaultValue("de") String language)
        throws Exception {
    log.info(String.format("Get document. mnr=%s, docno=%s, lang=%s", machineno, documentno, language));

    File file = new DocFileHelper(request).getDocumentForMachine(machineno, documentno, language);
    if (file == null) {
        log.error("File not found");
        return Response .status(404)
                        .build();
    }

    StreamingOutput stream = new StreamingOutput() {
        @Override
        public void write(OutputStream out) throws IOException, WebApplicationException {
            log.info("Stream file: " + file);
            try (FileInputStream inp = new FileInputStream(file)) {
                byte[] buff = new byte[1024];
                int len = 0;
                while ((len = inp.read(buff)) >= 0) {
                    out.write(buff, 0, len);
                }
                out.flush();
            } catch (Exception e) {
                log.log(Level.ERROR, "Stream file failed", e);
                throw new IOException("Stream error: " + e.getMessage());
            } finally {
                log.info("Remove stream file: " + file);
                file.delete();
            }
        }
    };

    return Response .ok(stream)
                    .build();
}