Статьи

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

Загрузка и выгрузка файлов и общие задачи в веб-приложении Java . Так как в последнее время я много писал о java-сервлете , я подумал предоставить пример примера загрузки и выгрузки файла с использованием сервлета.

Случай использования

Наш вариант использования — предоставить простую HTML-страницу, где клиент может выбрать локальный файл для загрузки на сервер. После отправки запроса на загрузку файла наша программа-сервлет загрузит файл в каталог на сервере, а затем предоставит URL-адрес, по которому пользователь может загрузить файл. По соображениям безопасности пользователю не будет предоставлен прямой URL для загрузки файла, вместо этого ему будет предоставлена ​​ссылка для загрузки файла, и наш сервлет обработает запрос и отправит файл пользователю.

Мы создадим динамический веб-проект в Eclipse, и структура проекта будет выглядеть как на картинке ниже.

Servlet-File-Upload-Скачать

Давайте рассмотрим все компоненты нашего веб-приложения и разберемся с реализацией.

HTML-страница для загрузки файла

Мы можем загрузить файл на сервер, отправив запрос на отправку сервлету и отправив форму. Мы не можем использовать метод GET для загрузки файла. Еще один момент, на который следует обратить внимание, это то, что тип формы должен быть multipart / form-data . Чтобы выбрать файл из файловой системы пользователя, нам нужно использовать элемент ввода с типом как файл . Таким образом, у нас может быть простая HTML-страница для загрузки файла:

index.html

01
02
03
04
05
06
07
08
09
10
<html>
<head></head>
<body>
<form action="UploadDownloadFileServlet" method="post" enctype="multipart/form-data">
Select File to Upload:<input type="file" name="fileName">
<br>
<input type="submit" value="Upload">
</form>
</body>
</html>

Расположение файла сервера

Нам нужно сохранить файл в некотором каталоге на сервере, мы можем жестко закодировать этот каталог в программе, но для большей гибкости мы будем сохранять его настраиваемым в параметрах контекста дескриптора развертывания. Также мы добавим html-страницу нашего файла загрузки в список файлов приветствия.

Наш файл web.xml будет выглядеть следующим образом:

web.xml

01
02
03
04
05
06
07
08
09
10
11
<?xml version="1.0" encoding="UTF-8"?>
  <display-name>ServletFileUploadDownloadExample</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
  </welcome-file-list>
  <context-param>
    <param-name>tempfile.dir</param-name>
    <param-value>tmpfiles</param-value>
  </context-param>
</web-app>

Реализация ServletContextListener

Поскольку нам нужно прочитать параметр контекста для местоположения файла и создать из него объект File, мы можем написать ServletContextListener, чтобы сделать это при инициализации контекста. Мы можем установить абсолютное местоположение каталога и объект File как атрибут контекста, который будет использоваться другими сервлетами.

Наш код реализации ServletContextListener подобен ниже.

FileLocationContextListener.java

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package com.journaldev.servlet;
 
import java.io.File;
 
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
 
@WebListener
public class FileLocationContextListener implements ServletContextListener {
 
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        String rootPath = System.getProperty("catalina.home");
        ServletContext ctx = servletContextEvent.getServletContext();
        String relativePath = ctx.getInitParameter("tempfile.dir");
        File file = new File(rootPath + File.separator + relativePath);
        if(!file.exists()) file.mkdirs();
        System.out.println("File Directory created to be used for storing files");
        ctx.setAttribute("FILES_DIR_FILE", file);
        ctx.setAttribute("FILES_DIR", rootPath + File.separator + relativePath);
    }
 
    public void contextDestroyed(ServletContextEvent servletContextEvent) {
        //do cleanup if needed
    }
 
}

Загрузка файла Скачать Внедрение сервлета

Для загрузки файлов мы будем использовать утилиту Apache Commons FileUpload , для нашего проекта мы используем версию 1.3, FileUpload зависит от jar Apache Commons IO , поэтому нам нужно поместить оба файла в каталог lib проекта, как вы можете видеть выше. изображение для структуры проекта.

Мы будем использовать фабрику DiskFileItemFactory, которая предоставляет метод для анализа объекта HttpServletRequest и возврата списка FileItem . FileItem предоставляет полезный метод для получения имени файла, имени поля в форме, размера и типа содержимого, подробностей файла, который должен быть загружен. Чтобы записать файл в каталог, нам нужно только создать объект File и передать его в качестве аргумента методу FileItem write () .

Поскольку целью сервлета является загрузка файла, мы переопределим метод init () для инициализации DiskFileItemFactory объекта DiskFileItemFactory сервлета. Мы будем использовать этот объект в реализации метода doPost () для загрузки файла в каталог сервера.

Как только файл будет успешно загружен, мы отправим клиенту ответ с URL-адресом для его загрузки, поскольку HTML-ссылки используют метод GET, мы добавим параметр для имени файла в URL-адрес и можем использовать тот же метод doGet () сервлета, чтобы реализовать процесс загрузки файла.

Для реализации сервлета загрузки файла сначала откроем InputStream для файла и используем метод ServletContext.getMimeType (), чтобы получить MIME-тип файла и установить его в качестве типа содержимого ответа.

Нам также нужно будет указать длину содержимого ответа как длину файла. Чтобы клиент понял, что мы отправляем файл в ответ, нам нужно установить заголовок « Content-Disposition » со значением « attachment»; имя файла = «имя файла» .

Как только мы закончим с настройкой конфигурации ответа, мы можем прочитать содержимое файла из InputStream и записать его в ServletOutputStream и очистить вывод для клиента.

Наша окончательная реализация сервлета UploadDownloadFileServlet выглядит следующим образом.

UploadDownloadFileServlet.java

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
package com.journaldev.servlet;
 
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Iterator;
import java.util.List;
 
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
 
@WebServlet("/UploadDownloadFileServlet")
public class UploadDownloadFileServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
    private ServletFileUpload uploader = null;
    @Override
    public void init() throws ServletException{
        DiskFileItemFactory fileFactory = new DiskFileItemFactory();
        File filesDir = (File) getServletContext().getAttribute("FILES_DIR_FILE");
        fileFactory.setRepository(filesDir);
        this.uploader = new ServletFileUpload(fileFactory);
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String fileName = request.getParameter("fileName");
        if(fileName == null || fileName.equals("")){
            throw new ServletException("File Name can't be null or empty");
        }
        File file = new File(request.getServletContext().getAttribute("FILES_DIR")+File.separator+fileName);
        if(!file.exists()){
            throw new ServletException("File doesn't exists on server.");
        }
        System.out.println("File location on server::"+file.getAbsolutePath());
        ServletContext ctx = getServletContext();
        InputStream fis = new FileInputStream(file);
        String mimeType = ctx.getMimeType(file.getAbsolutePath());
        response.setContentType(mimeType != null? mimeType:"application/octet-stream");
        response.setContentLength((int) file.length());
        response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
 
        ServletOutputStream os       = response.getOutputStream();
        byte[] bufferData = new byte[1024];
        int read=0;
        while((read = fis.read(bufferData))!= -1){
            os.write(bufferData, 0, read);
        }
        os.flush();
        os.close();
        fis.close();
        System.out.println("File downloaded at client successfully");
    }
 
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        if(!ServletFileUpload.isMultipartContent(request)){
            throw new ServletException("Content type is not multipart/form-data");
        }
 
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();
        out.write("<html><head></head><body>");
        try {
            List<FileItem> fileItemsList = uploader.parseRequest(request);
            Iterator<FileItem> fileItemsIterator = fileItemsList.iterator();
            while(fileItemsIterator.hasNext()){
                FileItem fileItem = fileItemsIterator.next();
                System.out.println("FieldName="+fileItem.getFieldName());
                System.out.println("FileName="+fileItem.getName());
                System.out.println("ContentType="+fileItem.getContentType());
                System.out.println("Size in bytes="+fileItem.getSize());
 
                File file = new File(request.getServletContext().getAttribute("FILES_DIR")+File.separator+fileItem.getName());
                System.out.println("Absolute Path at server="+file.getAbsolutePath());
                fileItem.write(file);
                out.write("File "+fileItem.getName()+ " uploaded successfully.");
                out.write("<br>");
                out.write("<a href=\"UploadDownloadFileServlet?fileName="+fileItem.getName()+"\">Download "+fileItem.getName()+"</a>");
            }
        } catch (FileUploadException e) {
            out.write("Exception in uploading file.");
        } catch (Exception e) {
            out.write("Exception in uploading file.");
        }
        out.write("</body></html>");
    }
 
}

Пример выполнения проекта показан на рисунках ниже.

Servlet-File-Upload-Form

Servlet-File-Upload-Success

Servlet-File-Скачать

Вы можете скачать Apache Commons IO jar и Apache Commons FileUpload jar по указанным ниже URL-адресам.

Обновления :

Входящие условия поиска:

Ссылка: сервлет Загрузить файл и загрузить пример файла от нашего партнера JCG Панкаджа Кумара в блоге Developer Recipes .