Я бачив декілька пропозицій, як, наприклад, щоб каталог зображень був символічним посиланням, що вказує на каталог поза веб-контейнером, але чи буде такий підхід працювати як у Windows, так і * nix?
Якщо ви дотримуєтесь правил шляху до файлової системи * nix (тобто ви використовуєте виключно передні косої риски, як у /path/to/files
), то вона також буде працювати і в Windows, без необхідності поспішати з потворними File.separator
рядками. Однак він буде сканований лише на тому ж робочому диску, що і звідки викликана ця команда. Отже, якщо Tomcat, наприклад, встановлений на, C:
тоді це /path/to/files
насправді вказувати б C:\path\to\files
.
Якщо всі файли знаходяться за межами веб-сторінки, і ви хочете, щоб Tomcat працював з DefaultServlet
ними, то все, що вам потрібно зробити в Tomcat, - це додати наступний елемент контексту до /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 не вибере правильне ім’я файлу під час Save As .
Ви можете використовувати ту саму логіку для обслуговування файлів із бази даних. Просто замініть new FileInputStream()
на ResultSet#getInputStream()
.
Сподіваюся, це допомагає.
Дивитися також: