Немного теории
В Spring MVC приложении, что бы скачать файл через браузер нужно выполнить следующие условия:
- Ничего не возвращаем, в сигнатуре будет
voidи добавимHttpServletResponseв качестве аргумента метода. - Определить в
HttpServletResponsecontent type (далее тип содержимого) на тип содержимого нашего файла. Если вы не знаете, что такое тип содержимого, или хотите, чтобы браузер всегда отображал диалоговое окно «Сохранить как», установите егоAPPLICATION/OCTET-STREAM(не чувствителен к регистру) - Добавить заголовок ответа HTTP с именем Content-Disposition и присвойте ему значение attachment; filename=fileName, где fileName — имя файла по умолчанию.
Контроллер скачивания файла
Рассмотрим пример реализации контроллера загрузки файлов, в моем случае Excel документы.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
@RequestMapping(value = "/files/{file_name:.+}", method = RequestMethod.GET) public void getFile(@PathVariable("file_name") String fileName, HttpServletResponse response) { // Прежде всего стоит проверить, если необходимо, авторизован ли пользователь и имеет достаточно прав на скачивание файла. Если нет, то выбрасываем здесь Exception //Авторизованные пользователи смогут скачать файл Path file = Paths.get(PathUtil.getUploadedFolder(), fileName); if (Files.exists(file)){ response.setHeader("Content-disposition", "attachment;filename=" + fileName); response.setContentType("application/vnd.ms-excel"); try { Files.copy(file, response.getOutputStream()); response.getOutputStream().flush(); } catch (IOException e) { LOG.info("Error writing file to output stream. Filename was '{}'" + fileName, e); throw new RuntimeException("IOError writing file to output stream"); } } } |
[stextbox id=’info’]Если вы хотите включить загрузку только для авторизованных пользователей, сначала проверьте имеет ли пользователь доступ к этому методу, а затем разрешите загрузку в противном случае стоит перенаправить его на экран входа в систему[/stextbox]
Предотвращение перекрестных ссылок на файлы
Другие сайты могут использовать перекрестные ссылки на ваши файлы используя их(файлы) как свои. Мы можем запретить подобные случаи. Чтобы запретить все запросы на загрузку из других доменов, вы можете проверить, содержит ли заголовок referer ваше доменное имя.
Наш модифицированный FileController отправит файлы в браузер, только если заголовок referer не равен null. Это предотвратит загрузку изображений напрямую, введя их URL-адреса в браузере или запрос, поступающий из других доменов.
|
1 2 3 4 5 6 7 |
@RequestMapping(value = "/files/{file_name:.+}", method = RequestMethod.GET) public void getFile(@PathVariable("file_name") String fileName, @RequestHeader String referer, HttpServletResponse response) { if (referer == null || referer.isEmpty()) throw new RefererException("Missing header 'referer' when try download file: " + fileName); //... } |