Servlet3.0 新特性——HttpServletRequest 对文件上传的支持
2017-07-10 00:00
645 查看
此前,对于处理上传文件的操作一直是让开发者头疼的问题,因为 Servlet 本身没有对此提供直接的支持,需要使用第三方框架( commons-io + commons-fileupload )来实现,而且使用起来也不够简单。如今这都成为了历史,Servlet 3.0 已经提供了这个功能,而且使用也非常简单。为此,HttpServletRequest 提供了两个方法用于从请求中解析出上传的文件:
Part getPart(String name)
Collection<Part> getParts()
前者用于获取请求中给定 name 的文件,后者用于获取所有的文件。每一个文件用一个 javax.servlet.http.Part 对象来表示。该接口提供了处理文件的简易方法,比如 write()、delete() 等。至此,结合 HttpServletRequest 和 Part 来保存上传的文件变得非常简单,如下所示:
另外,开发者可以配合前面提到的 @MultipartConfig 注解来对上传操作进行一些自定义的配置,比如限制上传文件的大小,以及保存文件的路径等。
需要注意的是,如果请求的 MIME 类型不是 multipart/form-data,则不能使用上面的两个方法,否则将抛异常。
具体配置如下:
1. form 的method必须是post的,get不能上传文件。 还需要加上enctype="multipart/form-data" 表示提交的数据是二进制文件
<form action="uploadPhoto" method="post" enctype="multipart/form-data">
2. 需要提供type="file" 的字段进行上传
Part getPart(String name)
Collection<Part> getParts()
前者用于获取请求中给定 name 的文件,后者用于获取所有的文件。每一个文件用一个 javax.servlet.http.Part 对象来表示。该接口提供了处理文件的简易方法,比如 write()、delete() 等。至此,结合 HttpServletRequest 和 Part 来保存上传的文件变得非常简单,如下所示:
1 2 3 | Part photo = request.getPart("photo"); photo.write("/tmp/photo.jpg"); // 可以将两行代码简化为 request.getPart("photo").write("/tmp/photo.jpg") 一行。 |
需要注意的是,如果请求的 MIME 类型不是 multipart/form-data,则不能使用上面的两个方法,否则将抛异常。
具体配置如下:
准备上传页面 upload.jsp
上传页面有两点需要注意1. form 的method必须是post的,get不能上传文件。 还需要加上enctype="multipart/form-data" 表示提交的数据是二进制文件
<form action="uploadPhoto" method="post" enctype="multipart/form-data">
2. 需要提供type="file" 的字段进行上传
<%@ page language="java" pageEncoding="UTF-8"%> <!DOCTYPE HTML> <html> <head> <title>Servlet3.0实现文件上传</title> </head> <body> <fieldset> <legend> 上传单个文件 </legend> <!-- 文件上传时必须要设置表单的enctype="multipart/form-data"--> <form action="${pageContext.request.contextPath}/UploadServlet" method="post" enctype="multipart/form-data"> 上传文件: <input type="file" name="file"> <br> <input type="submit" value="上传"> </form> </fieldset> <hr /> <fieldset> <legend> 上传多个文件 </legend> <!-- 文件上传时必须要设置表单的enctype="multipart/form-data"--> <form action="${pageContext.request.contextPath}/UploadServlet" method="post" enctype="multipart/form-data"> 姓名:<input name="username" type="text"><br> 上传文件: <input type="file" name="file1"> <br> 上传文件: <input type="file" name="file2"><br> 上传文件: <input type="file" name="file3"> 性别:<input name="sex" type="text"><br> <br> <input type="submit" value="上传"> </form> </fieldset> <%=application.getRealPath("/WEB-INF/uploadFile")%> </body> </html>
准备 UploadPhotoServlet
import java.io.File; import java.io.IOException; import java.io.PrintWriter; import java.util.Collection; import javax.servlet.ServletException; import javax.servlet.annotation.MultipartConfig; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.Part; //使用@WebServlet配置UploadServlet的访问路径 @WebServlet(name = "UploadServlet", urlPatterns = "/UploadServlet") // 使用注解@MultipartConfig将一个Servlet标识为支持文件上传 @MultipartConfig // 标识Servlet支持文件上传 public class UploadServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // System.out.println(request.getParameter("username")); // 存储路径 String savePath = request.getServletContext().getRealPath( "/WEB-INF/uploadFile"); File f = new File(savePath); if (!f.exists()) { f.mkdirs(); } // 获取上传的文件集合,重中之重,切记! Collection<Part> parts = request.getParts(); // 上传单个文件 String username; // 一次性上传多个文件 for (Part part : parts) {// 循环处理上传的文件 if (part.getHeader("content-disposition").indexOf("filename") == -1) { username = request.getParameter("username"); } else { // 获取请求头,请求头的格式:form-data; name="file"; // filename="snmp4j--api.zip" String header = part.getHeader("content-disposition"); // 获取文件名 String fileName = getFileName(header); // 把文件写到指定路径 part.write(savePath + File.separator + fileName); } } // 处理业务逻辑 //username PrintWriter out = response.getWriter(); out.println("上传成功"); out.flush(); out.close(); } /** * 根据请求头解析出文件名 请求头的格式:火狐和google浏览器下:form-data; name="file"; * filename="snmp4j--api.zip" IE浏览器下:form-data; name="file"; * filename="E:\snmp4j--api.zip" * * @param header * 请求头 * @return 文件名 */ public String getFileName(String header) { /** * String[] tempArr1 = * header.split(";");代码执行完之后,在不同的浏览器下,tempArr1数组里面的内容稍有区别 * 火狐或者google浏览器下: * tempArr1={form-data,name="file",filename="snmp4j--api.zip"} * IE浏览器下:tempArr1={form-data,name="file",filename="E:\snmp4j--api.zip"} */ String[] tempArr1 = header.split(";"); /** * 火狐或者google浏览器下:tempArr2={filename,"snmp4j--api.zip"} * IE浏览器下:tempArr2={filename,"E:\snmp4j--api.zip"} */ String[] tempArr2 = tempArr1[2].split("="); // 获取文件名,兼容各种浏览器的写法 String fileName = tempArr2[1].substring( tempArr2[1].lastIndexOf("\\") + 1).replaceAll("\"", ""); return fileName; } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doGet(request, response); } }
相关文章推荐
- Servlet 3.0 新特性详解(五)ServletContext 的性能增强及HttpServletRequest 对文件上传的支持
- HttpServletRequest 对文件上传的支持
- Servlet3.0中HttpServletRequest增加了对文件上传的支持
- 用servlet实现文件上传报错java.lang.NoSuchMethodError: javax.servlet.http.HttpServletRequest.getPart
- Servlet 3.0新特性——文件上传接口
- Spring中MultipartHttpServletRequest实现文件上传
- Spring 文件上传 MultipartHttpServletRequest
- Servlet 3.0新特性——文件上传接口
- 使用common-fileUpload和 Spring中MultipartHttpServletRequest实现文件上传
- Spring中MultipartHttpServletRequest实现文件上传 生成缩略图
- Servlet 3.0笔记之超方便的文件上传支持
- Servlet 3.0笔记之超方便的文件上传支持
- Servlet3.0新特性之文件上传
- Spring中MultipartHttpServletRequest实现文件上传
- 上传文件(文件非必填)MultipartHttpServletRequest
- Spring中MultipartHttpServletRequest实现文件上传
- Struts2 中用Fileupload上传文件得不到HttpServletRequest值的解决办法
- spring中的文件上传:MultipartHttpServletRequest
- 【Servlet3.0新特性】第03节_文件上传
- spring mvc 中上传文件时根本就不访问HttpServletRequest请求的解决方案