Загрузка файлов с сервлетами и JSP

Загрузка файлов с сервлетами и JSP

1. Вступление

В этом кратком руководстве мы увидим, как загрузить файл из сервлета.

Чтобы добиться этого, мы сначала увидим обычное решение Java EE с возможностями загрузки файлов, обеспечиваемыми встроенной аннотацией@MultipartConfig.

Затем мы рассмотрим библиотеку Apache CommonsFileUpload для более ранних версий Servlet API.

2. Использование Java EE@MultipartConfig

Начиная с версии 6, Java EE имеет возможность сразу же поддерживать загрузку нескольких частей.

Таким образом, это, вероятно, стандартное решение при добавлении в приложение Java EE поддержки загрузки файлов.

Во-первых, давайте добавим форму в наш HTML-файл:

Choose a file:

Форма должна быть определена с использованием атрибутаenctype=”multipart/form-data”, чтобы сигнализировать о многокомпонентной загрузке.

Далееwe’ll want to annotate our HttpServlet with the correct information using the @MultipartConfig annotation:

@MultipartConfig(fileSizeThreshold = 1024 * 1024,
  maxFileSize = 1024 * 1024 * 5,
  maxRequestSize = 1024 * 1024 * 5 * 5)
public class MultipartServlet extends HttpServlet {
    //...
}

Затем давайте убедимся, что настроена наша папка загрузки на сервере по умолчанию:

String uploadPath = getServletContext().getRealPath("") + File.separator + UPLOAD_DIRECTORY;
File uploadDir = new File(uploadPath);
if (!uploadDir.exists()) uploadDir.mkdir();

Наконец,we can easily retrieve our inbound File from the request using the getParts() method и сохраните его на диск:

for (Part part : request.getParts()) {
    fileName = getFileName(part);
    part.write(uploadPath + File.separator + fileName);
}

Обратите внимание, что в этом примере мы используем вспомогательный метод getFileName ():

private String getFileName(Part part) {
    for (String content : part.getHeader("content-disposition").split(";")) {
        if (content.trim().startsWith("filename"))
            return content.substring(content.indexOf("=") + 2, content.length() - 1);
        }
    return Constants.DEFAULT_FILENAME;
}

Для сервлета 3.1. проектов, в качестве альтернативы мы могли бы использовать методPart.getSubmittedFileName():

fileName = part.getSubmittedFileName();

3. Использование Apache Commons FileUpload

Если мы не работаем над проектом Servlet 3.0, мы можем напрямую использовать библиотеку Apache Commons FileUpload.

3.1. Настроить

Мы хотим использовать следующие зависимостиpom.xml, чтобы запустить наш пример:


    commons-fileupload
    commons-fileupload
    1.3.3


    commons-io
    commons-io
    2.6

Самые последние версии можно найти с помощью быстрого поиска в центральном репозитории Maven:commons-fileupload иcommons-io.

3.2. Загрузить сервлет

Три основные части включения библиотеки ApacheFileUpload заключаются в следующем:

  • Форма загрузки на странице.jsp.

  • Настройка вашего объектаDiskFileItemFactory иServletFileUpload.

  • Обработка фактического содержимого многочастной загрузки файла.

Форма загрузки такая же, как в предыдущем разделе.

Перейдем к созданию нашего сервлета Java EE.

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

Мы также укажем, какие ресурсы выделить для загрузки файла временно (во время обработки) на нашемDiskFileItemFactory.

Наконец,we’ll create a ServletFileUpload object which will represent the actual file itself. Он предоставит содержимое загрузки из нескольких частей для окончательной персистентности на стороне сервера:

if (ServletFileUpload.isMultipartContent(request)) {

    DiskFileItemFactory factory = new DiskFileItemFactory();
    factory.setSizeThreshold(MEMORY_THRESHOLD);
    factory.setRepository(new File(System.getProperty("java.io.tmpdir")));

    ServletFileUpload upload = new ServletFileUpload(factory);
    upload.setFileSizeMax(MAX_FILE_SIZE);
    upload.setSizeMax(MAX_REQUEST_SIZE);
    String uploadPath = getServletContext().getRealPath("")
      + File.separator + UPLOAD_DIRECTORY;
    File uploadDir = new File(uploadPath);
    if (!uploadDir.exists()) {
        uploadDir.mkdir();
    }
    //...
}

И тогда мы можем извлечь это содержимое и записать их на диск:

if (ServletFileUpload.isMultipartContent(request)) {
    //...
    List formItems = upload.parseRequest(request);
    if (formItems != null && formItems.size() > 0) {
        for (FileItem item : formItems) {
        if (!item.isFormField()) {
            String fileName = new File(item.getName()).getName();
            String filePath = uploadPath + File.separator + fileName;
                File storeFile = new File(filePath);
                item.write(storeFile);
                request.setAttribute("message", "File "
                  + fileName + " has uploaded successfully!");
        }
        }
    }
}

4. Запуск примера

После того, как мы скомпилировали наш проект в.war, мы можем поместить его в локальный экземпляр Tomcat и запустить.

Оттуда мы можем вызвать главное окно загрузки, где нам представлена ​​форма:

image

После успешной загрузки вашего файла, мы должны увидеть сообщение:

image

Наконец, мы можем проверить местоположение, указанное в нашем сервлете:

image

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

Это оно! Мы узнали, как обеспечить загрузку файлов из нескольких частей с помощью Java EE, а также библиотеки CommonFileUpload Apache!

Фрагменты кода, как всегда, можно найтиover on GitHub.