servlet 3.0实现文件上传文件
http请求头 content-type常见的值有,x-www-form-urlencoded,multipart/form-data,application/json三种 ,servlet对这三种类型的请求有不同的处理方式。
servlet3.0需要tomcat7+,jdk1.6+支持。
1 package cn.xxx; 2 3 import javax.servlet.ServletException; 4 import javax.servlet.ServletInputStream; 5 import javax.servlet.annotation.MultipartConfig; 6 import javax.servlet.http.HttpServlet; 7 import javax.servlet.http.HttpServletRequest; 8 import javax.servlet.http.HttpServletResponse; 9 import javax.servlet.http.Part; 10 import java.io.*; 11 import java.util.Collection; 12 import java.util.Enumeration; 13 14 /** 15 * 默认的content-type是content-type=application/x-www-form-urlencoded 16 * 上传文件时,content-type必须是: multipart/form-data,等,multipart类型,本质是通过流的形式上传 17 */ 18 19 @MultipartConfig 20 public class FileUploadServlet extends HttpServlet { 21 22 /** 23 * 处理所有POST请求 24 * 25 * @param request 26 * @param response 27 * @throws javax.servlet.ServletException 28 * @throws IOException 29 */ 30 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 31 request.setCharacterEncoding("utf-8"); 32 response.setCharacterEncoding("utf-8"); 33 // 打印所有请求头 34 printAllHeaders(request, response); 35 // 打印所有请求参数,form中, 36 printAllparames(request, response); 37 String contentType = request.getHeader("content-type"); 38 if ("application/json".equals(contentType)) { 39 handleJsonRequest(request, response); 40 } else if (null != contentType && contentType.contains("multipart")) { 41 // 处理Mutipart请求 42 handleMutipartRequest(request, response); 43 } else { 44 handleNonMutipartRequest(request, response); 45 } 46 PrintWriter out = response.getWriter(); 47 out.write("success!"); 48 out.flush(); 49 out.close(); 50 } 51 52 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws javax.servlet.ServletException, IOException { 53 doPost(request, response); 54 } 55 56 /** 57 * 打印所有请求头 58 * 59 * @param request 60 * @param response 61 */ 62 private void printAllHeaders(HttpServletRequest request, HttpServletResponse response) { 63 Enumeration<String> hNames = request.getHeaderNames(); 64 String headerName = null; 65 while (hNames.hasMoreElements()) { 66 headerName = hNames.nextElement(); 67 System.out.println(headerName + "=" + request.getHeader(headerName)); 68 } 69 System.out.println("=====以上是request的所有header====="); 70 } 71 72 /** 73 * 打印所有请求参数 74 * 75 * @param request 76 * @param response 77 */ 78 private void printAllparames(HttpServletRequest request, HttpServletResponse response) { 79 Enumeration<String> parameterNames = request.getParameterNames(); 80 String paramName = null; 81 while (parameterNames.hasMoreElements()) { 82 paramName = parameterNames.nextElement(); 83 System.out.println(paramName + "=" + request.getParameter(paramName)); 84 } 85 System.out.println("=====以上是request的所有Parameter====="); 86 // 结论: 除file的值外,其它的的值是可以通过.request.getParameter("name"); 获取的 87 } 88 89 90 private void handleNonMutipartRequest(HttpServletRequest request, HttpServletResponse response) { 91 System.out.println("没有multipart..."); 92 } 93 94 /** 95 * 处理multipart请求 96 * 97 * @param request 98 * @param response 99 * @throws IOException 100 * @throws ServletException 101 */ 102 private void handleMutipartRequest(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { 103 // 如果haader中Content-Type属性没有,mutipart/form-data等mutipar类型的值的话,调用request.getParts()这个方法会报错。 104 Collection<Part> parts = request.getParts(); 105 106 // 读取所有文件 107 for (Part part : parts) { 108 109 // part = request.getPart("myfile"); ,根据part 的Name 获得指定part, 110 // partName 与表单中的name属性一致:如<input type="file" name="myfile"> 111 System.out.println("当前part的名字是:" + part.getName()); 112 113 /********** 测试Part对象带有哪些header属性:开始**********/ 114 Collection<String> headerNames = part.getHeaderNames(); 115 for (String name : headerNames) { 116 System.out.println(name + "=" + part.getHeader(name)); 117 } 118 /** 119 * 结果一: 120 * content-type=image/png 121 * content-disposition=form-data; name="myfile"; filename="102247307079625130.png" 122 * 结果二: 123 * content-type=text/plain 124 * content-disposition=form-data; name="myfile"; filename="idea 快捷键.txt" 125 * 结果三: 126 * content-disposition=form-data; name="id" 127 * 结论:file类型的Part的header有两个属性 128 * content-type是选择的文件的类型 129 * content-disposition是文件名及form表单中name名字 130 * 如果不是file类型的input,是没有content-type属性的 131 */ 132 /********** 测试Part对象带有哪些header属性:结束***********/ 133 134 String contentDisposition = part.getHeader("content-disposition"); 135 // 区分file和其它input 136 if (contentDisposition != null && contentDisposition.contains("filename")) { 137 //System.out.println(contentDisposition); 138 // 保存文件到指定目录 139 part.write("D:\\" + getFileName(contentDisposition)); 140 System.out.println("文件已经保存到:" + "D:\\" + getFileName(contentDisposition)); 141 } else { 142 InputStream is = part.getInputStream(); 143 byte[] b = new byte[1024]; 144 int a = is.read(b); 145 System.out.println(part.getName() + "=" + new String(b)); 146 is.close(); 147 } 148 } 149 } 150 151 private void handleJsonRequest(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { 152 ServletInputStream servletInputStream = request.getInputStream(); 153 BufferedReader br = new BufferedReader(new InputStreamReader(servletInputStream)); 154 StringBuffer stringBuffer = new StringBuffer(); 155 String strLine = null; 156 while ((strLine = br.readLine()) != null) { 157 stringBuffer.append(strLine); 158 } 159 System.out.println("jsonData:::" + stringBuffer); 160 servletInputStream.close(); 161 br.close(); 162 } 163 164 /** 165 * 从content-disposition中解析出文件名称 166 * 167 * @param contentDisposition 168 * @return 169 */ 170 private String getFileName(String contentDisposition) { 171 String[] strs1 = contentDisposition.split(";"); 172 String fileName = strs1[2].split("=")[1]; 173 return fileName.replaceAll("\"", ""); 174 } 175 }
web.xml配置
1 <?xml version="1.0" encoding="UTF-8"?> 2 <web-app version="2.4" 3 xmlns="http://java.sun.com/xml/ns/j2ee" 4 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 5 xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> 6 7 <servlet> 8 <servlet-name>FileUploadServlet</servlet-name> 9 <servlet-class>cn.mamp.FileUploadServlet</servlet-class> 10 </servlet> 11 <servlet-mapping> 12 <servlet-name>FileUploadServlet</servlet-name> 13 <url-pattern>/up</url-pattern> 14 </servlet-mapping> 15 </web-app>
pom.xml依赖
1 <dependencies> 2 <dependency> 3 <groupId>javax.servlet</groupId> 4 <artifactId>javax.servlet-api</artifactId> 5 <version>3.1.0</version> 6 <scope>provided</scope> 7 </dependency> 8 </dependencies>
测试页面
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 </head> 7 <body> 8 <!--file和其它表单元素混合--> 9 <form action="http://localhost:8090/web/up" method="post" enctype="multipart/form-data"> 10 <input type="file" name="myfile"> 11 <input type="text" name="id"> 12 <input type="text" name="name"> 13 <input type="submit" value="submit"> 14 </form> 15 <!--多个file元素--> 16 <form action="http://localhost:8090/web/up" method="post" enctype="multipart/form-data"> 17 <input type="file" name="myfile1"> 18 <input type="file" name="myfile2"> 19 <input type="submit" value="submit"> 20 </form> 21 <!--没有file元素--> 22 <form action="http://localhost:8090/web/up" method="post"> 23 <input type="text" name="id"> 24 <input type="text" name="name"> 25 <input type="submit" value="submit"> 26 </form> 27 28 </body> 29 </html>