Если ты:
- Не хотите загружать весь файл в
byte[]
перед отправкой ответа;
- Хотите / нужно отправить / скачать через
InputStream
;
- Хотите иметь полный контроль над Mime Type и именем отправляемого файла;
- Есть другие
@ControllerAdvice
исключения для вас (или нет).
Код ниже - то, что вам нужно:
@RequestMapping(value = "/stuff/{stuffId}", method = RequestMethod.GET)
public ResponseEntity<FileSystemResource> downloadStuff(@PathVariable int stuffId)
throws IOException {
String fullPath = stuffService.figureOutFileNameFor(stuffId);
File file = new File(fullPath);
long fileLength = file.length(); // this is ok, but see note below
HttpHeaders respHeaders = new HttpHeaders();
respHeaders.setContentType("application/pdf");
respHeaders.setContentLength(fileLength);
respHeaders.setContentDispositionFormData("attachment", "fileNameIwant.pdf");
return new ResponseEntity<FileSystemResource>(
new FileSystemResource(file), respHeaders, HttpStatus.OK
);
}
О части длины файла :File#length()
должно быть достаточно хорошо в общем случае, но я подумал, что сделаю это наблюдение, потому что оно может быть медленным , и в этом случае вы должны сохранить его ранее (например, в БД). Случаи, которые могут быть медленными, включают: если файл большой, особенно если файл находится в удаленной системе или что-то более сложное, например, - база данных, может быть.
InputStreamResource
Если ваш ресурс не является файлом, например, вы берете данные из БД, вы должны использовать InputStreamResource
. Пример:
InputStreamResource isr = new InputStreamResource(new FileInputStream(file));
return new ResponseEntity<InputStreamResource>(isr, respHeaders, HttpStatus.OK);