Пример загрузки файла в сервлет

Пример загрузки файла в сервлет

 1. обзор

Общей особенностью веб-приложений является возможность загрузки файлов.

В этом руководствеwe’ll cover a simple example of creating a downloadable file and serving it from a Java Servlet application.

Используемый нами файл будет взят из ресурсов веб-приложения.

2. Maven Зависимости

If using Java EE, then we wouldn’t need to add any dependencies. Однако, если мы используем Java SE, нам понадобится зависимость javax.servlet-api:


    javax.servlet
    javax.servlet-api
    4.0.1
    provided

Последнюю версию зависимости можно найтиhere.

3. Servlet

Давайте сначала посмотрим на код, а потом выясним, что происходит:

@WebServlet("/download")
public class DownloadServlet extends HttpServlet {
    private final int ARBITARY_SIZE = 1048;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
      throws ServletException, IOException {

        resp.setContentType("text/plain");
        resp.setHeader("Content-disposition", "attachment; filename=sample.txt");

        try(InputStream in = req.getServletContext().getResourceAsStream("/WEB-INF/sample.txt");
          OutputStream out = resp.getOutputStream()) {

            byte[] buffer = new byte[ARBITARY_SIZE];

            int numBytesRead;
            while ((numBytesRead = in.read(buffer)) > 0) {
                out.write(buffer, 0, numBytesRead);
            }
        }
    }
}

3.1. Запросить конечную точку

Аннотация@WebServlet(“/download”) отмечает классDownloadServlet для обслуживания запросов, направленных в точку отправки“/download” .

В качестве альтернативы мы можем сделать это, описав сопоставление в файле web.xml.

3.2. ОтветContent-Type

У объектаHttpServletResponse есть метод, называемыйsetContentType, который мы можем использовать для установки заголовкаContent-Type ответа HTTP.

Content-Type - это историческое имя свойства заголовка. Другое название было MIME-тип (многоцелевые расширения почты Интернета). Теперь мы просто ссылаемся на значение как Тип носителя.

This value could be “application/pdf”, “text/plain”, “text/html”, “image/jpg”, etc., официальный список ведется Управлением по присвоению номеров Интернета (IANA), и его можно найти вhere.

Для нашего примера мы используем простой текстовый файл. The Content-Type for a text file is “text/plain”.с

3.3. ОтветContent-Disposition

Установка заголовкаContent-Disposition в объекте ответа сообщает браузеру, как обрабатывать файл, к которому он обращается.

Браузеры понимают использованиеContent-Disposition как соглашение, но на самом деле это не часть стандарта HTTP. В W3 есть памятка об использованииContent-Disposition для чтенияhere.

ЗначенияContent-Disposition для основной части ответа будут либо «встроенными» (для отображения содержимого веб-страницы), либо «вложением» (для загружаемого файла).

Если не указан, по умолчаниюContent-Disposition является «встроенным».

Используя необязательный параметр заголовка, мы можем указать имя файла «sample.txt».

Некоторые браузеры немедленно загружают файл, используя указанное имя файла, а другие показывают диалог загрузки, содержащий наше предопределенное значение.

Точное действие будет зависеть от браузера.

3.4. Чтение из файла и запись в выходной поток

В оставшихся строках кода мы беремServletContext из запроса и используем его для получения файла по адресу «/WEB-INF/sample.txt».

Затем, используяHttpServletResponse #getOutputStream(), мы читаем из входного потока ресурса и записываем вOutputStream ответа.

Размер байтового массива, который мы используем, является произвольным. Мы можем решить размер на основе объема памяти, который разумно выделить для передачи данных отInputStream кOutputStream; чем меньше номер, тем больше петель; чем больше число, тем выше потребление памяти.

Этот цикл продолжается до тех пор, покаnumByteRead не станет равным 0, так как это указывает на конец файла.

3.5. Закрыть и Флеш

ЭкземплярыStream должны быть закрыты после использования, чтобы освободить все ресурсы, которые он в настоящее время удерживает. ЭкземплярыWriter также должны быть сброшены для записи оставшихся буферизованных байтов в место назначения.

Используя операторtry-with-resources, приложение автоматическиclose будет использовать любой экземплярAutoCloseable, определенный как часть оператораtry. Узнайте больше о try-with-resourceshere.

Мы используем эти два метода для освобождения памяти, гарантируя, что подготовленные данные отправляются из нашего приложения.

3.6. Скачивание файла

Теперь, когда все готово, мы готовы запустить наш сервлет.

Теперь, когда мы посещаем относительную конечную точку“/download”, наш браузер попытается загрузить файл как «simple.txt».

4. Заключение

Загрузка файла из сервлета становится простым процессом. Использование потоков позволяет нам передавать данные в виде байтов, а типы мультимедиа информируют браузер клиента, какой тип данных ожидать.

Браузер должен определить, как обрабатывать ответ, однако мы можем дать некоторые рекомендации с заголовкомContent-Disposition.

Весь код в этой статье можно найти вover on GitHub.