This question already has an answer here:
-
Write an InputStream to an HttpServletResponse
3 answers
What is the best way to handle deleting a file after it has been returned as the response to a REST request?
I have an endpoint that creates a file on request and returns it in the response. Once the response has been dispatched the file is no longer needed and can/should be removed.
@Path("file")
@GET
@Produces({MediaType.APPLICATION_OCTET_STREAM})
@Override
public Response getFile() {
// Create the file
...
// Get the file as a steam for the entity
File file = new File("the_new_file");
ResponseBuilder response = Response.ok((Object) file);
response.header("Content-Disposition", "attachment; filename=\"the_new_file\"");
return response.build();
// Obviously I can't do this but at this point I need to delete the file!
}
I guess I could create a tmp file but I would have thought there was a more elegant mechanism to achieve this. The file could be quite large so I cannot load it into memory.
There is a more elegant solution, don't write a file, just write directly to the output stream contained in the instance of Response
.
Use a StreamingOutput as entity:
final Path path;
...
return Response.ok().entity(new StreamingOutput() {
@Override
public void write(final OutputStream output) throws IOException, WebApplicationException {
try {
Files.copy(path, output);
} finally {
Files.delete(path);
}
}
}
Without knowing the context of your application, you can delete the file when the VM exits:
file.deleteOnExit();
See: https://docs.oracle.com/javase/7/docs/api/java/io/File.html#deleteOnExit%28%29
I did something like this recently in rest service development using jersey
@GET
@Produces("application/zip")
@Path("/export")
public Response exportRuleSet(@QueryParam("ids") final List<String> ids) {
try {
final File exportFile = serviceClass.method(ruleSetIds);
final InputStream responseStream = new FileInputStream(exportFile);
StreamingOutput output = new StreamingOutput() {
@Override
public void write(OutputStream out) throws IOException, WebApplicationException {
int length;
byte[] buffer = new byte[1024];
while((length = responseStream.read(buffer)) != -1) {
out.write(buffer, 0, length);
}
out.flush();
responseStream.close();
boolean isDeleted = exportFile.delete();
log.info(exportFile.getCanonicalPath()+":File is deleted:"+ isDeleted);
}
};
return Response.ok(output).header("Content-Disposition", "attachment; filename=rulset-" + exportFile.getName()).build();
}
save the response in a tmp variable with replacing your return statement like this:
Response res = response.build();
//DELETE your files here.
//maybe this is not the best way, at least it is a way.
return res;
send file name on response:
return response.header("filetodelete", FILE_OUT_PUT).build();
after that you can send delete restful method
@POST
@Path("delete/{file}")
@Produces(MediaType.TEXT_PLAIN)
public void delete(@PathParam("file") String file) {
File delete = new File(file);
delete.delete();
}