Spring @RestController - после обработки запроса
Фон
Вот метод, определенный в @RestController, он читает файл с диска, а затем возвращает поток.
@RequestMapping(value = "/bill", method = RequestMethod.GET)
public ResponseEntity<Object> getbill(){
...
InputStream in = new FileInputStream(file);
InputStreamResource inputStreamResource = new InputStreamResource(in);
httpHeaders.setContentLength(file.Length());
return new ResponseEntity(inputStreamResource, httpHeaders, HttpStatus.OK);
}
вопрос
Я хотел бы удалить файл после обработки запроса, но не могу найти подходящее место.
Я бы предположил, что это должно быть после закрытия inputStream ( https://github.com/spring-projects/spring-framework/blob/v4.3.9.RELEASE/spring-web/src/main/java/org/springframework/http/converter/ResourceHttpMessageConverter.java#L117). это нельзя сделать указанным выше методом, так как файл открывается Inputstream.
Резюме Ответа Спасибо всем за помощь в этом.
Принятый ответ требует наименьших изменений и работает хорошо.
3 ответа
Простираться FileInputStream
с вашей собственной реализацией, а затем переписать close
, Когда входной поток закрыт, ваш файл также удаляется.
public class MyFileInputStream extends FileInputStream {
private final File myFile;
public MyFileInputStream(File file) throws FileNotFoundException {
super(file);
myFile = file;
}
@Override
public void close() throws IOException {
super.close();
myFile.delete();
}
}
Несмотря на тот факт, что в службе RESTfull выполнять деструктивные операции над запросами GET недопустимо, это не может быть сделано библиотеками Java по умолчанию. Более широко принятой реализацией будет GET, который транслирует файл с последующим вызовом DELETE для его удаления.
Но вы можете сделать это, реализовав свой собственный InputStream, см. Более раннюю тему в Stackru об удалении файлов при закрытии InputStream.
Предполагая, что вы создаете файл в том же контроллере. Ты можешь использовать:
try (BufferedWriter out = Files
.newBufferedWriter(newFilePath, Charset.defaultCharset(),
StandardOpenOption.DELETE_ON_CLOSE)) {
InputStream in = new FileInputStream(newFilePath.toFile());
InputStreamResource inputStreamResource = new InputStreamResource(in);
httpHeaders.setContentLength(file.Length());
return new ResponseEntity(inputStreamResource, httpHeaders, HttpStatus.OK);
} catch (Exception e) {
}
Когда BufferedWriter закроется по возвращении, файл будет удален.
Основываясь на ответе @phlogratos, вы можете попробовать вот так.
@GetMapping("/download")
public ResponseEntity<InputStreamResource> download() throws Exception {
... codes ...
InputStreamResource isr = new InputStreamResource(new FileInputStream(file) {
@Override
public void close() throws IOException {
super.close();
boolean isDeleted = file.delete();
logger.info("export:'{}':" + (isDeleted ? "deleted" : "preserved"), filename);
}
});
return new ResponseEntity<>(isr, respHeaders, HttpStatus.OK);
}