我从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();
}