Servlet 3.1 文件上传
Java Servlet 可以与 HTML form 标签一起使用,允许用户上传文件到服务器
上传的文件可以是文本文件或图像文件或任何文档
注意: Servlet 3 已经内置了文件上传这一特性,开发者不再需要将 Commons FileUpload 组件导入到工程中去
创建一个文件上传表单
下面的 HTML 代码创建了一个文件上传表单
有以下几点需要注意
- 表单 method 属性应该设置为 POST 方法,不能使用 GET 方法
- 表单 enctype 属性应该设置为 multipart/form-data
-
表单 action 属性应该设置为在后端服务器上处理文件上传的 servlet 文件
下面的范例使用了 UploadServlet Servlet 来上传文件 -
上传单个文件,应该使用单个带有属性
type="file"
的<input .../>
标签
为了允许多个文件上传,请包含多个 name 属性值不同的 input 标签
输入标签具有不同的名称属性的值,浏览器会为每个 input 标签关联一个浏览按钮
webapp/form-upload.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <meta charset="UTF-8"> <title>文件上传范例 - Servlet 基础教程 | 简单教程(www.twle.cn)</title> <h3>文件上传范例 - Servlet 基础教程 | 简单教程(www.twle.cn) </h3> <form method="post" action="/servlet/post_upload" enctype="multipart/form-data"> <p>选择一个文件: <input type="file" name="uploadFile" /></p> <p><input type="submit" value="上传" /></p> </form>
cn/twle/demo/UploadServlet.java
// author: 简单教程(www.twle.cn) // Copyright © 2015-2065 www.twle.cn. All rights reserved. package cn.twle.demo; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; import java.sql.*; import javax.servlet.annotation.WebServlet; import javax.servlet.annotation.MultipartConfig; import java.util.List; @WebServlet(name = "UploadServlet", urlPatterns = {"post_upload"}) //使用注解 @MultipartConfig 将一个 Servlet 标识为支持文件上传 //标识Servlet支持文件上传 @MultipartConfig(location="upload",maxFileSize = 1024*1024*20) public class UploadServlet extends HttpServlet { public static final String UPLOAD_DIRECTORY = "upload"; private static final long serialVersionUID = 1L; private static MultipartConfig config = UploadServlet.class.getAnnotation(MultipartConfig.class); public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("UTF-8"); Part part = null; try{ part = request.getPart("uploadFile");//获取 part 用于处理上传的文件 }catch(IllegalStateException ise) { //上传的单个文件超出 maxFileSize 或者上传的总的数据量超出 maxRequestSize 时会抛出此异常 //如果注解中没设置此项,那就是单个文件超出限制 if(config.maxRequestSize() == -1L) request.setAttribute("message","错误信息: 单个文件超限"); else if(config.maxFileSize() == -1L) //如果注解中没有设置单个文件最大限制,那就是总数据量超限。 request.setAttribute("message","错误信息: 总数据量超限"); else request.setAttribute("message","错误信息: Error"); // 跳转到 message.jsp request.getServletContext().getRequestDispatcher("/message.jsp").forward( request, response); } if(part == null) return; //获得上传的文件名,没有判断用户没有选择文件直接提交的情况 //没有判断上传文件失败的情况 String fileName = part.getSubmittedFileName(); String message = ""; message += "<p>contentType : " + part.getContentType() + "</p>"; message += "<p>fileName : " + fileName + "</p>"; message += "<p>fileSize : " + part.getSize() + "</p>"; message += "<p>header names :<br/>"; for(String headerName : part.getHeaderNames()) message += headerName + " : " + part.getHeader(headerName) + "<br/>"; message += "</p>"; //为了避免文件重名,将时间组合到了文件名中。实际项目中可以考虑使用用户主键或者生成一个唯一的ID来组合文件名。 String saveName = System.currentTimeMillis() + "_" + fileName; // 构造临时路径来存储上传的文件 // 这个路径相对当前应用的目录 String uploadPath = request.getServletContext().getRealPath("./") + File.separator + UPLOAD_DIRECTORY; // 如果目录不存在则创建 File uploadDir = new File(uploadPath); if (!uploadDir.exists()) { uploadDir.mkdir(); } String fullPath = uploadPath + File.separator + saveName; //part.write(fullPath); //将上传的文件保存到磁盘,默认是注解中location的相对地址,也可以传入一个绝对路径 InputStream in = part.getInputStream(); OutputStream out = new FileOutputStream(fullPath); byte[] buffer = new byte[1024]; int length = -1; while ((length = in.read(buffer)) != -1) { out.write(buffer, 0, length); } in.close(); out.close(); System.out.println(fullPath); message += "<p>文件上传成功!</p>"; message += "<p><img src=\"/servlet/upload/" + saveName + "\"/></p>"; request.setAttribute("message",message); // 跳转到 message.jsp request.getServletContext().getRequestDispatcher("/message.jsp").forward( request, response); } }
webapp/message.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <meta charset="utf-8" /> <title>文件上传结果 | Servlet 基础教程 | 简单教程(www.twle.cn) </title> <p>Servlet 基础教程 | 简单教程(www.twle.cn)</p> <p>${message}</p>
配置 web.xml 文件添加以内容
<servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>/upload/*</url-pattern> </servlet-mapping>
在浏览器上输入 http://localhost:8080/servlet/form-upload.jsp 显示结果如下