Servlet 上传文件和下载文件示例

Servlet Upload File and Download File 是 [java web application](/community/tutorials/java-web-application-tutorial-for-beginners Java Web Application Tutorial for Beginners)中常见的一项任务,因为我最近写了很多关于 [java servlet](/community/tutorials/servlet-jsp-tutorial Java Servlet Tutorial with Examples for Beginners)的文章,所以我想给您提供一个示例的 servlet 文件上传到服务器,然后从服务器下载到客户端。

服务器上传文件

Our use case is to provide a simple HTML page where client can select a local file to be uploaded to server. On submission of request to upload the file, our servlet program will upload the file into a directory in the server and then provide the URL through which user can download the file. For security reason, user will not be provided direct URL for downloading the file, rather they will be given a link to download the file and our servlet will process the request and send the file to user. We will create a dynamic web project in Eclipse and the project structure will look like below image. Servlet Upload File, java upload file to server, servlet download file Let's look into all the components of our web application and understand the implementation.

HTML 页面用于 Java 上传文件到服务器

我们不能使用 GET 方法上传文件. 另一个要注意的点是,表单的 enctype 应该是 multipart/form-data. 要从用户文件系统中选择一个文件,我们需要使用 input 元素与 type 作为 file

 1<html>
 2<head></head>
 3<body>
 4<form action="UploadDownloadFileServlet" method="post" enctype="multipart/form-data">
 5Select File to Upload:<input type="file" name="fileName">
 6<br>
 7<input type="submit" value="Upload">
 8</form>
 9</body>
10</html>

文件上传服务器文件的位置

我们需要将文件存储在服务器上的某个目录中,我们可以将此目录硬编码在程序中,但为了更好的灵活性,我们将保持在部署描述器背景参数中可配置。

 1<?xml version="1.0" encoding="UTF-8"?>
 2<web-app xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns="https://java.sun.com/xml/ns/javaee" xsi:schemaLocation="https://java.sun.com/xml/ns/javaee https://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
 3  <display-name>ServletFileUploadDownloadExample</display-name>
 4  <welcome-file-list>
 5    <welcome-file>index.html</welcome-file>
 6  </welcome-file-list>
 7  <context-param>
 8    <param-name>tempfile.dir</param-name>
 9    <param-value>tmpfiles</param-value>
10  </context-param>
11</web-app>

ServletContextListener 用于文件上传位置

由于我们需要读取文件位置的语境参数,并从中创建一个文件对象,我们可以编写一个ServletContextListener在语境初始化时这样做。

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

文件上传下载服务器

** Update**:Servlet Specs 3在API中增加了上传服务器上文件的支持,因此我们不需要使用任何第三方API. 请检查access-date=中的日期值 (帮助) [Servlet 3上传文件] (/community/tourises/ servlet-3-file-upload-multipconfig-part "Servlet 3 文件上传使用多部分配置注释和部分界面". 在文件上传时,我们将使用Apache Communitys FileUpload 工具,因为我们正在使用1.3版本的项目,FileUpload依赖于Apache Communitys IO 罐,所以我们需要将两者都放入工程的lib目录中,正如您在图像上可以看到的,用于工程结构. 我们将使用 ** DiskFile 项目 Factory ** 工厂,该工厂提供了分析 HttpServlet 请求对象和返回 ** File 项目列表的方法。 文件项目为获取需要上传的文件的文件名,字段名的形式,大小和内容类型细节提供了有用的方法. 要将文件写入目录, 我们只需创建一个文件对象, 并将其传递给文件项目 ** write () ** 方法 。 由于服务器的全部目的都是上传文件,我们将推翻init () 方法,将服务器的 DiskFile 项目 Factory 对象实例禁用。 我们将使用 doPost () 方法执行中的此对象上传文件到服务器目录 。 一旦文件成功上传,我们将用 URL 向客户端发送下载文件的回复,因为 HTML 链接使用 GET 方法,我们将在 URL 中附加文件名参数, 我们可以使用同样的 servlet doGet () 方法执行文件下载进程 。 为了实施下载文件服务器,我们首先会打开文件的输入站并使用ServletContext.getMimeType()方法获取文件的MIME类型并设定为响应内容类型. 我们还需要将响应内容长度设定为文件长度. 为了确保客户端理解我们发送文件以回应,我们需要设置"Content-Disposition"标题,其值为""attachment;file="fileName"**. 一旦设定了响应配置,我们就可以从IntitionStream读取文件内容并写入ServletOutputStream,将输出冲到客户端. 我们最后执行的上传DownloadFileServlet servlet看起来像下面.

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

The sample execution of the project is shown in below images. Servlet File Upload HTML JSP Form Servlet File Upload to Server Servlet Download File

点击下载下载下载下载下载下载下载

您可以從下面的 URL 下載 Apache Commons IO jar 和 Apache Commons FileUpload jar。 https://commons.apache.org/proper/commons-fileupload/download_fileupload.cgi https://commons.apache.org/proper/commons-io/download_io.cgi

[下载 标签 标签 标签 标签 标签 标签 标签 标签 标签]

请参阅关于 系列的下一篇文章(/社区/教程/servlet-exception-and-error-handling-example-tutorialServlet Exception and Error Handling Example Tutorial)

Published At
Categories with 技术
Tagged with
comments powered by Disqus