一。在Servlet中增加了Part接口。可以更加方便的进行文件上传处理,可以通过request的getPart()方法取得Part接口。
下面的HTML是上传文件的代码。
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <form action="upload2.do" method="post" enctype="multipart/form-data"> 上传照片:<input type="file" name="photo"><br/><br/> <input type="submit" value="上传" name="upload"> </form> </body> </html>
用下面的servlet来处理上传的文件
1 package com.sunyongxing.servlet; 2 3 import java.io.FileOutputStream; 4 import java.io.IOException; 5 import java.io.InputStream; 6 import java.io.OutputStream; 7 8 import javax.servlet.ServletException; 9 import javax.servlet.annotation.MultipartConfig; 10 import javax.servlet.annotation.WebServlet; 11 import javax.servlet.http.HttpServlet; 12 import javax.servlet.http.HttpServletRequest; 13 import javax.servlet.http.HttpServletResponse; 14 import javax.servlet.http.Part; 15 16 /** 17 * Servlet implementation class UploadServlet 18 */ 19 @MultipartConfig 20 @WebServlet("/upload.do") 21 public class UploadServlet extends HttpServlet { 22 private static final long serialVersionUID = 1L; 23 24 protected void doPost(HttpServletRequest request, 25 HttpServletResponse response) throws ServletException, IOException { 26 request.setCharacterEncoding("utf-8"); 27 Part part = request.getPart("photo"); 28 String fileName = getFileName(part); 29 writeTo(fileName,part); 30 } 31 32 private void writeTo(String fileName, Part part)throws IOException { 33 InputStream in = part.getInputStream(); 34 OutputStream out = new FileOutputStream("d:/"+fileName); 35 byte[] b = new byte[1024]; 36 int length = -1; 37 while((length = in.read(b))!=-1) 38 { 39 out.write(b, 0, length); 40 } 41 in.close(); 42 out.close(); 43 } 44 45 private String getFileName(Part part) { 46 String head = part.getHeader("Content-Disposition"); 47 String fileName = head.substring(head.indexOf("filename=\"")+10, head.lastIndexOf("\"")); 48 System.out.println(fileName); 49 return fileName; 50 } 51 52 }
Tomcat中必须设置@MultipartConfig标注才能使用getPart()相关API,否则会返回null。getFileName()方法获取上传的文件名是通过对标头信息的解析,因为每一个multipart/form-data发送的每个内容区段(这些内容可以通过request的getReade()方法获得,见getReader的文件),都会有以下的标头信息:
Content-Disposition:form-data;name="photo";filename="haha.jpg"
Content-Type:image/jpeg
.......
对@MultipartConfig标注的说明。@MultipartConfig标注有一下的属性可用。
fileSizeThreshold:整数值设置,默认值为0,若上传文件的大小超过了这个值,就会先写入缓存文件。
location:字符串设置,默认值为空字符串。如果设置这个属性,缓存文件就是写到制定目录,下面举例说明
maxFileSize:限制文件上传大小。默认值为-1L,表示不限制大小。
maxRequestSize:限制multipart/form-data请求格式,默认值为-1L,表示不限制个数。
二。Part接口的进一步介绍
Part接口有一个write()方法。可以直接将上传文件写入磁盘中,参数为上传的文件名,写入的路径就是@MultipartConfig的location设置的路径,见下面的servlet。
1 package com.sunyongxing.servlet; 2 3 import java.io.IOException; 4 5 import javax.servlet.ServletException; 6 import javax.servlet.annotation.MultipartConfig; 7 import javax.servlet.annotation.WebServlet; 8 import javax.servlet.http.HttpServlet; 9 import javax.servlet.http.HttpServletRequest; 10 import javax.servlet.http.HttpServletResponse; 11 import javax.servlet.http.Part; 12 13 /** 14 * Servlet implementation class UploadServlet 15 */ 16 @MultipartConfig(location="E:/jsp") 17 @WebServlet("/upload2.do") 18 public class UploadServlet2 extends HttpServlet { 19 private static final long serialVersionUID = 1L; 20 21 protected void doPost(HttpServletRequest request, 22 HttpServletResponse response) throws ServletException, IOException { 23 request.setCharacterEncoding("utf-8"); 24 Part part = request.getPart("photo"); 25 String fileName = getFileName(part); 26 part.write(fileName); 27 } 28 29 30 31 private String getFileName(Part part) { 32 String head = part.getHeader("Content-Disposition"); 33 String fileName = head.substring(head.indexOf("filename=\"")+10, head.lastIndexOf("\"")); 34 System.out.println(fileName); 35 return fileName; 36 } 37 38 }
三。上传多个文件的处理方法。
如果一次上传多个文件,可以使用getParts()方法,会返回一个Collection<Part>。例子的html如下:
1 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 2 <html> 3 <head> 4 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 5 <title>Insert title here</title> 6 </head> 7 <body> 8 <form action="upload3.do" method="post" enctype="multipart/form-data"> 9 上传文件: 10 <input type="file" name="photo1"><br/> 11 <input type="file" name="photo2"><br/> 12 <input type="file" name="photo3"><br/>+ 13 <input type="submit" value="上传" name="upload"> 14 </form> 15 </body> 16 </html>
处理多个文件同时上传的servlet如下
1 package com.sunyongxing.servlet; 2 3 import java.io.IOException; 4 5 import javax.servlet.ServletException; 6 import javax.servlet.annotation.MultipartConfig; 7 import javax.servlet.annotation.WebServlet; 8 import javax.servlet.http.HttpServlet; 9 import javax.servlet.http.HttpServletRequest; 10 import javax.servlet.http.HttpServletResponse; 11 import javax.servlet.http.Part; 12 13 /** 14 * Servlet implementation class UploadServlet 15 */ 16 @MultipartConfig(location = "E:/jsp") 17 @WebServlet("/upload3.do") 18 public class UploadServlet3 extends HttpServlet { 19 private static final long serialVersionUID = 1L; 20 21 protected void doPost(HttpServletRequest request, 22 HttpServletResponse response) throws ServletException, IOException { 23 request.setCharacterEncoding("utf-8"); 24 for (Part part : request.getParts()) { 25 if (part.getName().startsWith("photo")) { 26 String fileName = getFileName(part); 27 part.write(fileName); 28 } 29 30 } 31 } 32 33 private String getFileName(Part part) { 34 String head = part.getHeader("Content-Disposition"); 35 String fileName = head.substring(head.indexOf("filename=\"") + 10, 36 head.lastIndexOf("\"")); 37 System.out.println(fileName); 38 return fileName; 39 } 40 41 }
上面代码的红字部分值得注意,表示只处理上传文件的区段,因为三个上传文件的标头信息还可能会有其他的标头信息,不做处理就会发生错误,这里面是根据html中上传文件元素的name属性来判断的,注意区分。
这里介绍了servlet3.0的Part接口的使用,确实简化了对上传文件的处理过程。以上代码都是运行通过的,文章内容取自servlet&jsp学习笔记第二版。