Servlet上傳文件

目錄(?)[+]html

 

上傳文件

Servlet的參數設置

採用annotation方式以下:java

[java]  view plain   copy
 
   
  1. @WebServlet(  
  2.     name = "TicketServlet",  
  3.     urlPatterns = {"/tickets"},  
  4.     loadOnStartup = 1  
  5.     )  
  6. /* MultipartConfig配置了本Servlet的文件上傳參數, 
  7.  * location:這裏沒有列出的是location參數,表示存放臨時文件的位置,通常無需配置,選擇缺省的臨時文件夾 
  8.  * fileSizeThreshold:表示收到文件到達這麼大後,不在放入緩存,而是寫入臨時文件。本例中,若是文件小於5M,則存放在緩存,而後被垃圾回收;一樣的,若是採用臨時文件方式,臨時文件也會被刪除。 
  9.  * maxFileSize:限制文件的最大值,本例文件不超過20M 
  10.  * maxRequestSize:因爲可能同時上傳多個文件,servlet可能會被同時請求,此限制總量。  
  11.  */  
  12. @MultipartConfig(    
  13.     fileSizeThreshold = 5_242_880, // 5M  
  14.     maxFileSize = 20_971_520L, //20M  
  15.     maxRequestSize = 41_943_040L //40M  
  16.     )  

 

採用web.xml的方式以下:web

[html]  view plain   copy
 
   
  1. <servlet>  
  2.     <multipart-config>  
  3.         <location>......</location>  
  4.         <file-size-threshold>......</file-size-threshold>  
  5.         <max-file-size>......</<max-file-size>  
  6.         <max-request-size>......</max-request-size>  
  7.     </multipart-config>  
  8. </servlet>  

Multipart上傳文件

下面是Create Ticket的HTML,文件上傳有關的是<form… enctype="multipart/form-data"/>和<input type="file" name="file1"/>緩存

[html]  view plain   copy
 
   
  1. <!DOCTYPE html>  
  2.   <html>  
  3.   <head>  
  4.     <title>Customer Support</title>  
  5.   </head>  
  6.   <body>  
  7.     <h2>Create a Ticket</h2>  
  8.     <form method="POST" action="tickets" enctype="multipart/form-data">  
  9.       <input type="hidden" name="action" value="create"/>  
  10.       Your Name<br/>  
  11.       <input type="text" name="customerName"/><br/><br/>  
  12.       Subject<br/>  
  13.       <input type="text" name="subject"/><br/><br/>  
  14.       Body<br/>  
  15.       <textarea name="body" rows="5" cols="30"></textarea><br/><br/>  
  16.       <b>Attachments</b><br/>  
  17.       <input type="file" name="file1"/><br/><br/>  
  18.       <input type="submit" value="Submit"/>  
  19.     </form>  
  20.   </body>  
  21. </html>  

 

點擊submite,將觸發一個action=create的POST請求,抓包以下:app

[plain]  view plain   copy
 
   
  1. POST /customer-support/tickets HTTP/1.1  
  2. Host: 191.8.1.103:8080  
  3. User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:42.0) Gecko/20100101 Firefox/42.0  
  4. Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8  
  5. Accept-Language: en-US,en;q=0.5  
  6. Accept-Encoding: gzip, deflate  
  7. Referer: http://191.8.1.103:8080/customer-support/tickets?action=create  
  8. Connection: keep-alive  
  9. Content-Type: multipart/form-data; boundary=---------------------------168557226814076645131805352216  
  10. Content-Length: 729  
  11.   
  12. -----------------------------168557226814076645131805352216  
  13. Content-Disposition: form-data; name="action"  
  14.   
  15. create  
  16. -----------------------------168557226814076645131805352216  
  17. Content-Disposition: form-data; name="customerName"  
  18.   
  19. Wei  
  20. -----------------------------168557226814076645131805352216  
  21. Content-Disposition: form-data; name="subject"  
  22.   
  23. moon  
  24. -----------------------------168557226814076645131805352216  
  25. Content-Disposition: form-data; name="body"  
  26.   
  27. Hello,world  
  28. -----------------------------168557226814076645131805352216  
  29. Content-Disposition: form-data; name="file1"; filename="moon.txt"  
  30. Content-Type: text/plain  
  31.   
  32. Hello, Moon!  
  33. Hello, my friend!  
  34.   
  35. -----------------------------168557226814076645131805352216--  

先對比普通的form-data的HTTP POST消息體的例子以下。和GET的參數傳遞部分是同樣的。ide

 

action=create&customerName=j&subject=jj&body=jjjjurl

 

如今,咱們在HTML中指明enctype="multipart/form-data",所以在HTTP POST的封裝中採用了multipart/form-data的方式。這在RFC1867 Form-based File Uploadin HTML中有詳細的規定,包括file類型。對於普通的form-data的內容讀取有下面兩個方式:orm

(1)經過javax.servlet.http.part類來讀取xml

[java]  view plain   copy
 
   
  1. Part part1 = request.getPart("customerName");  
  2. System.out.println(part1.getHeader("Content-Disposition"));  
  3. InputStream is = part1.getInputStream();  
  4. int len = is.available();  
  5. byte[] buff = new byte[len];  
  6. is.read(buff);  
  7. System.out.println(new String(buff));  

(2)提供了更直接的方式htm

[java]  view plain   copy
 
   
  1. System.<em>out</em>.println(<strong>request.getParameter("customerName"));</strong>  

 

毫無疑問,咱們會採用第二種方式,可是第一種方式提供了通用的讀取multipart的方法。咱們將使用該方式讀取上傳文件部分,小例子的代碼以下:

[java]  view plain   copy
 
   
  1. private void createTicket(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{  
  2.     //獲取普通的form-data信息  
  3.     String customerName = request.getParameter("customerName");  
  4.     String subject = request.getParameter("subject");  
  5.     String body = request.getParameter("body");  
  6.   
  7.     //讀取上傳文件部分:獲取相應的multipart  
  8.     Part filePart = request.getPart("file1");  
  9.     //讀取上傳文件部分:getSize()是multipart中信息的大小,而非整個multipart的大小,對應即爲上傳文件的大小  
  10.     if(filePart != null && filePart.getSize() > 0){  
  11.         // 獲取文件名稱,即Content-Disposition: form-data; name="file1"; filename="moon.txt"中的filename,咱們能夠經過filePart.getHeader("Content-Disposition")分析獲取。javax.servlet.http.Part直接提供了方法  
  12.         String fileName = filePart.getSubmittedFileName();  
  13.         // 獲取文件上傳內容放。  
  14.         InputStream inputStream = filePart.getInputStream();  
  15.         ByteArrayOutputStream outputStream = new ByteArrayOutputStream();  
  16.         int read;  
  17.         final byte[] bytes = new byte[1024];  
  18.         while((read = inputStream.read(bytes)) != -1){  
  19.             outputStream.write(bytes, 0, read);  
  20.         }  
  21.         /* 若是是二進制,經過outputStream.toByteArray()得到byte[]。任何格式均適合二進制;若是是文本文件,能夠先經過filePart.getHeader("Content-Type")來確認,直接outputStream.toString() */  
  22.           … …  
  23.     }  
  24.     ......  
  25. }  

上傳文件

Servlet的參數設置

採用annotation方式以下:

[java]  view plain   copy
 
   
  1. @WebServlet(  
  2.     name = "TicketServlet",  
  3.     urlPatterns = {"/tickets"},  
  4.     loadOnStartup = 1  
  5.     )  
  6. /* MultipartConfig配置了本Servlet的文件上傳參數, 
  7.  * location:這裏沒有列出的是location參數,表示存放臨時文件的位置,通常無需配置,選擇缺省的臨時文件夾 
  8.  * fileSizeThreshold:表示收到文件到達這麼大後,不在放入緩存,而是寫入臨時文件。本例中,若是文件小於5M,則存放在緩存,而後被垃圾回收;一樣的,若是採用臨時文件方式,臨時文件也會被刪除。 
  9.  * maxFileSize:限制文件的最大值,本例文件不超過20M 
  10.  * maxRequestSize:因爲可能同時上傳多個文件,servlet可能會被同時請求,此限制總量。  
  11.  */  
  12. @MultipartConfig(    
  13.     fileSizeThreshold = 5_242_880, // 5M  
  14.     maxFileSize = 20_971_520L, //20M  
  15.     maxRequestSize = 41_943_040L //40M  
  16.     )  

 

採用web.xml的方式以下:

[html]  view plain   copy
 
   
  1. <servlet>  
  2.     <multipart-config>  
  3.         <location>......</location>  
  4.         <file-size-threshold>......</file-size-threshold>  
  5.         <max-file-size>......</<max-file-size>  
  6.         <max-request-size>......</max-request-size>  
  7.     </multipart-config>  
  8. </servlet>  

Multipart上傳文件

下面是Create Ticket的HTML,文件上傳有關的是<form… enctype="multipart/form-data"/>和<input type="file" name="file1"/>

[html]  view plain   copy
 
   
  1. <!DOCTYPE html>  
  2.   <html>  
  3.   <head>  
  4.     <title>Customer Support</title>  
  5.   </head>  
  6.   <body>  
  7.     <h2>Create a Ticket</h2>  
  8.     <form method="POST" action="tickets" enctype="multipart/form-data">  
  9.       <input type="hidden" name="action" value="create"/>  
  10.       Your Name<br/>  
  11.       <input type="text" name="customerName"/><br/><br/>  
  12.       Subject<br/>  
  13.       <input type="text" name="subject"/><br/><br/>  
  14.       Body<br/>  
  15.       <textarea name="body" rows="5" cols="30"></textarea><br/><br/>  
  16.       <b>Attachments</b><br/>  
  17.       <input type="file" name="file1"/><br/><br/>  
  18.       <input type="submit" value="Submit"/>  
  19.     </form>  
  20.   </body>  
  21. </html>  

 

點擊submite,將觸發一個action=create的POST請求,抓包以下:

[plain]  view plain   copy
 
   
  1. POST /customer-support/tickets HTTP/1.1  
  2. Host: 191.8.1.103:8080  
  3. User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:42.0) Gecko/20100101 Firefox/42.0  
  4. Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8  
  5. Accept-Language: en-US,en;q=0.5  
  6. Accept-Encoding: gzip, deflate  
  7. Referer: http://191.8.1.103:8080/customer-support/tickets?action=create  
  8. Connection: keep-alive  
  9. Content-Type: multipart/form-data; boundary=---------------------------168557226814076645131805352216  
  10. Content-Length: 729  
  11.   
  12. -----------------------------168557226814076645131805352216  
  13. Content-Disposition: form-data; name="action"  
  14.   
  15. create  
  16. -----------------------------168557226814076645131805352216  
  17. Content-Disposition: form-data; name="customerName"  
  18.   
  19. Wei  
  20. -----------------------------168557226814076645131805352216  
  21. Content-Disposition: form-data; name="subject"  
  22.   
  23. moon  
  24. -----------------------------168557226814076645131805352216  
  25. Content-Disposition: form-data; name="body"  
  26.   
  27. Hello,world  
  28. -----------------------------168557226814076645131805352216  
  29. Content-Disposition: form-data; name="file1"; filename="moon.txt"  
  30. Content-Type: text/plain  
  31.   
  32. Hello, Moon!  
  33. Hello, my friend!  
  34.   
  35. -----------------------------168557226814076645131805352216--  

先對比普通的form-data的HTTP POST消息體的例子以下。和GET的參數傳遞部分是同樣的。

 

action=create&customerName=j&subject=jj&body=jjjj

 

如今,咱們在HTML中指明enctype="multipart/form-data",所以在HTTP POST的封裝中採用了multipart/form-data的方式。這在RFC1867 Form-based File Uploadin HTML中有詳細的規定,包括file類型。對於普通的form-data的內容讀取有下面兩個方式:

(1)經過javax.servlet.http.part類來讀取

[java]  view plain   copy
 
  
  1. Part part1 = request.getPart("customerName");  
  2. System.out.println(part1.getHeader("Content-Disposition"));  
  3. InputStream is = part1.getInputStream();  
  4. int len = is.available();  
  5. byte[] buff = new byte[len];  
  6. is.read(buff);  
  7. System.out.println(new String(buff));  

(2)提供了更直接的方式

[java]  view plain   copy
 
   
  1. System.<em>out</em>.println(<strong>request.getParameter("customerName"));</strong>  

 

毫無疑問,咱們會採用第二種方式,可是第一種方式提供了通用的讀取multipart的方法。咱們將使用該方式讀取上傳文件部分,小例子的代碼以下:

[java]  view plain   copy
 
   
  1. private void createTicket(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{  
  2.     //獲取普通的form-data信息  
  3.     String customerName = request.getParameter("customerName");  
  4.     String subject = request.getParameter("subject");  
  5.     String body = request.getParameter("body");  
  6.   
  7.     //讀取上傳文件部分:獲取相應的multipart  
  8.     Part filePart = request.getPart("file1");  
  9.     //讀取上傳文件部分:getSize()是multipart中信息的大小,而非整個multipart的大小,對應即爲上傳文件的大小  
  10.     if(filePart != null && filePart.getSize() > 0){  
  11.         // 獲取文件名稱,即Content-Disposition: form-data; name="file1"; filename="moon.txt"中的filename,咱們能夠經過filePart.getHeader("Content-Disposition")分析獲取。javax.servlet.http.Part直接提供了方法  
  12.         String fileName = filePart.getSubmittedFileName();  
  13.         // 獲取文件上傳內容放。  
  14.         InputStream inputStream = filePart.getInputStream();  
  15.         ByteArrayOutputStream outputStream = new ByteArrayOutputStream();  
  16.         int read;  
  17.         final byte[] bytes = new byte[1024];  
  18.         while((read = inputStream.read(bytes)) != -1){  
  19.             outputStream.write(bytes, 0, read);  
  20.         }  
  21.         /* 若是是二進制,經過outputStream.toByteArray()得到byte[]。任何格式均適合二進制;若是是文本文件,能夠先經過filePart.getHeader("Content-Type")來確認,直接outputStream.toString() */  
  22.           … …  
  23.     }  
  24.     ......  
  25. }  
相關文章
相關標籤/搜索