Загрузка и выгрузка файлов и общие задачи в веб-приложении Java . Так как в последнее время я много писал о java-сервлете , я подумал предоставить пример примера загрузки и выгрузки файла с использованием сервлета.
Случай использования
Наш вариант использования — предоставить простую HTML-страницу, где клиент может выбрать локальный файл для загрузки на сервер. После отправки запроса на загрузку файла наша программа-сервлет загрузит файл в каталог на сервере, а затем предоставит URL-адрес, по которому пользователь может загрузить файл. По соображениям безопасности пользователю не будет предоставлен прямой URL для загрузки файла, вместо этого ему будет предоставлена ссылка для загрузки файла, и наш сервлет обработает запрос и отправит файл пользователю.
Мы создадим динамический веб-проект в Eclipse, и структура проекта будет выглядеть как на картинке ниже.
Давайте рассмотрим все компоненты нашего веб-приложения и разберемся с реализацией.
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"?><web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> <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;@WebListenerpublic 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>"); }} |
Пример выполнения проекта показан на рисунках ниже.
Вы можете скачать Apache Commons IO jar и Apache Commons FileUpload jar по указанным ниже URL-адресам.
- http://commons.apache.org/proper/commons-fileupload/download_fileupload.cgi
- http://commons.apache.org/proper/commons-io/download_io.cgi
Обновления :
- Скачать ServletFileUploadDownloadExample Project
- Проверьте следующую статью в серии об обработке исключений сервлетов .



