一。在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學習筆記第二版。