Servlet 可以与 HTML form 标签一起使用,来允许用户上传文件到服务器。上传的文件可以是文本文件或图像文件或任何文档。
本文使用到的文件有:
- upload.jsp : 文件上传表单。
- message.jsp : 上传成功后跳转页面。
- UploadServlet.java : 上传处理 Servlet。
- 需要引入的 jar 文件:commons-fileupload-1.3.2、commons-io-2.5.jar。
创建一个文件上传表单
下面的 HTML 代码创建了一个文件上传表单。以下几点需要注意:
- 表单 method 属性应该设置为 POST 方法,不能使用 GET 方法。
- 表单 enctype 属性应该设置为 multipart/form-data.
- 表单 action 属性应该设置为在后端服务器上处理文件上传的 Servlet 文件。
- 上传单个文件,您应该使用单个带有属性 type="file" 的 <input .../> 标签。为了允许多个文件上传,请包含多个 name 属性值不同的 input 标签。输入标签具有不同的名称属性的值。浏览器会为每个 input 标签关联一个浏览按钮。
upload.jsp 文件代码如下:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>Title
编写后台Servlet
UploadServlet 的源代码 如下所示:
import org.apache.commons.fileupload.FileItem;import org.apache.commons.fileupload.FileUploadException;import org.apache.commons.fileupload.ProgressListener;import org.apache.commons.fileupload.disk.DiskFileItemFactory;import org.apache.commons.fileupload.servlet.FileCleanerCleanup;import org.apache.commons.fileupload.servlet.ServletFileUpload;import org.apache.commons.io.FileCleaningTracker;import org.apache.commons.io.FileUtils;import org.apache.commons.io.FilenameUtils;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.File;import java.io.IOException;import java.io.PrintWriter;import java.util.Iterator;import java.util.List;import java.util.Map;@WebServlet(name = "UploadServlet", urlPatterns = {"/upload"})public class UploadServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { if (!ServletFileUpload.isMultipartContent(request)) { PrintWriter writer = response.getWriter(); response.getWriter().println("Error: 表单必须包含 enctype=multipart/form-data"); writer.flush(); } else { int sizeThreshold = 10 * 1024;// 上传文件的阈值, 单位字节 long fileSizeMax = 10485760;// 上传文件的最大字节数 String realPath = getServletContext().getRealPath("/");// 获取应用在服务器根路径下的真实路径 System.out.println("contextPath: " + realPath); File saveDir = new File(realPath + "/resources");// 上传的文件保存的文件夹 File tempDir = new File(realPath + "/temp");// 上传的临时文件存储文件夹 DiskFileItemFactory factory = new DiskFileItemFactory();// 创建磁盘文件下载工厂处理类 factory.setSizeThreshold(sizeThreshold);// 设置文件直接写入磁盘的大小阈值。如果上传文件超过这个值,则会产生上传临时文件,保存在临时文件上 if (!tempDir.exists()) { // 如果临时文件缓存文件夹不存在,则创建一个文件夹 tempDir.mkdirs(); } factory.setRepository(tempDir);//设置临时文件保存目录 FileCleaningTracker tracker = FileCleanerCleanup.getFileCleaningTracker(request.getServletContext());// 文件清除追踪器 factory.setFileCleaningTracker(tracker);// 设置文件清除追踪器 ServletFileUpload fileUpload = new ServletFileUpload(factory);// 创建文件上传Servlet处理类 fileUpload.setHeaderEncoding("UTF-8");// 设置字符编码 fileUpload.setProgressListener(new ProgressListener() { public void update(long pBytesRead, long pContentLength, int pItems) { // pBytesRead:已经读到的字节数 // pContentLength:正在读取的文件的总字节总数。如果这个数字是未知的,可能是-1, // pItems:当前正在读取的在页面第几项。(0 =目前没有读取项,1 =第一项正在阅读,…) System.out.println("pBytesRead:" + pBytesRead + ", pContentLength:" + pContentLength + ", pItems:" + pItems); } });// 设置文件上传进度监听器 fileUpload.setFileSizeMax(fileSizeMax);// 设置文件上传的最大字节数,我这里设置为10M // 设置最大允许一个完整的请求的大小,而不是setFileSizeMax()。 // 允许的最大大小,以字节为单位。默认值- 1表示没有限制。 //fileUpload.setSizeMax(fileSizeMax); try { ListfileItems = fileUpload.parseRequest(request); Iterator iterator = fileItems.iterator(); while (iterator.hasNext()) { FileItem fileItem = iterator.next(); if (fileItem.isFormField()) { // 如果是表单数据 String fieldName = fileItem.getFieldName(); String value = fileItem.getString("UTF-8"); System.out.println("fieldName:" + fieldName + ", value:" + value); } else { // 如果是上传文件数据 if (fileItem.getSize() > 0) { // 文件大小大于0 String name = fileItem.getName();// 返回客户端文件系统中的原始文件名,由浏览器(或其他客户端软件)提供。 // 有可能包含路径,所以这里进行处理 String fileName = FilenameUtils.getName(name);// 通过Common io提供的工具类,获取文件名 // 通过FileUtils提供的工具方法进行文件保存操作 FileUtils.copyInputStreamToFile(fileItem.getInputStream(), new File(saveDir, fileName)); } } } } catch (FileUploadException e) { e.printStackTrace(); } } }}
运行项目,查看结果
在浏览器地址打开:http://localhost:8080/web/upload.jsp,出现下图页面。
输入表单内容,点击提交按钮后,在控制台出现如下结果
contextPath: C:\Users\Administrator\IdeaProjects\web\target\web\pBytesRead:4096, pContentLength:763062, pItems:0pBytesRead:4096, pContentLength:763062, pItems:1pBytesRead:4096, pContentLength:763062, pItems:2pBytesRead:4096, pContentLength:763062, pItems:3...... 此处省略多行pBytesRead:761772, pContentLength:763062, pItems:3pBytesRead:761856, pContentLength:763062, pItems:3pBytesRead:763062, pContentLength:763062, pItems:3fieldName:username, value:scottfieldName:password, value:tiger
大功告成,如果有什么问题,欢迎指正。