Я видел несколько предложений, например, чтобы каталог изображений был символической ссылкой, указывающей на каталог за пределами веб-контейнера, но будет ли этот подход работать как в среде Windows, так и в среде * nix?
Если вы придерживаетесь правил пути к файловой системе * nix (то есть используете исключительно прямые косые черты, как в /path/to/files), тогда он будет работать и в Windows без необходимости возиться с уродливыми File.separatorконкатенациями строк. Однако он будет сканироваться только на том же рабочем диске, с которого была вызвана эта команда. Так что, если Tomcat установлен, например, C:тогда /path/to/filesфактически будет указывать на C:\path\to\files.
Если все файлы расположены за пределами веб-приложения, и вы хотите, чтобы Tomcat DefaultServletобрабатывал их, все, что вам нужно сделать в Tomcat, - это добавить следующий элемент Context во /conf/server.xmlвнутренний <Host>тег:
<Context docBase="/path/to/files" path="/files" />
Таким образом, они будут доступны через http://example.com/files/.... Пример конфигурации GlassFish / Payara можно найти здесь, а пример конфигурации WildFly - здесь .
Если вы хотите , чтобы иметь контроль над чтением / запись файлов самостоятельно, то вам необходимо создать Servletдля этого , которое в основном только получает InputStreamиз файла в аромате, например , FileInputStreamи записывает его в OutputStreamиз HttpServletResponse.
В ответе вы должны установить Content-Typeзаголовок, чтобы клиент знал, какое приложение связать с предоставленным файлом. И вы должны установить Content-Lengthзаголовок, чтобы клиент мог рассчитать прогресс загрузки, иначе он будет неизвестен. И вы должны установить Content-Dispositionзаголовок, attachmentесли вы хотите диалоговое окно « Сохранить как », иначе клиент попытается отобразить его встроенным. Наконец, просто запишите содержимое файла в выходной поток ответа.
Вот базовый пример такого сервлета:
@WebServlet("/files/*")
public class FileServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
String filename = URLDecoder.decode(request.getPathInfo().substring(1), "UTF-8");
File file = new File("/path/to/files", filename);
response.setHeader("Content-Type", getServletContext().getMimeType(filename));
response.setHeader("Content-Length", String.valueOf(file.length()));
response.setHeader("Content-Disposition", "inline; filename=\"" + file.getName() + "\"");
Files.copy(file.toPath(), response.getOutputStream());
}
}
При отображении, url-patternнапример /files/*, на из , вы можете вызвать его по http://example.com/files/image.png. Таким образом, вы можете иметь больший контроль над запросами, чем DefaultServletони, например, предоставлять изображение по умолчанию (т.е. if (!file.exists()) file = new File("/path/to/files", "404.gif")или около того). Также request.getPathInfo()предпочтительнее использовать выше, request.getParameter()потому что он более дружественен к SEO, и в противном случае IE не выберет правильное имя файла при сохранении как .
Вы можете повторно использовать ту же логику для обслуживания файлов из базы данных. Просто замените new FileInputStream()на ResultSet#getInputStream().
Надеюсь это поможет.
Смотрите также: