使用fileupload實現檔案上傳(1)

來源:互聯網
上載者:User

標籤:input   npe   png   cte   名稱   編碼格式   測試   color   程式   

一. fileupload組件工作原理

先來張圖片, 協助大家理解

fileupload核心API

1. DiskFileItemFactory
構造器
1) DiskFileItemFactory() // 使用預設配置
2) DiskFileItemFactory(int sizeThreshold, File repository)
  sizeThreshold 記憶體緩衝區, 不能設定太大, 否則會導致JVM崩潰
  repository 臨時檔案目錄

2. ServletFileUpload
1) isMutipartContent(request) // 判斷上傳表單是否為multipart/form-data類型 true/false
2) parseRequest(request) // 解析request, 傳回值為List<FileItem>類型
3) setFileSizeMax(long) // 上傳檔案單個最大值
4) setSizeMax(long) // 上傳檔案總量最大值
5) setHeaderEncoding(String) // 設定編碼格式
6) setProgressListener(ProgressListener) // 設定監聽器, 可以用於製作進度條

 

二. 使用fileupload實現檔案上傳1. 編寫JSP
 1 <%@ page contentType="text/html;charset=UTF-8" language="java" %> 2 <html> 3 <head> 4     <title>示範檔案上傳</title> 5 </head> 6 <body> 7     <form action="${pageContext.request.contextPath}/servlet/FileUpload1" method="post" enctype="multipart/form-data"> 8         使用者名稱: <input type="text" name="username"/><br/> 9         檔案1: <input type="file" name="file1"/><br/>10         檔案2: <input type="file" name="file2"/><br/>11         <input type="submit"/>12     </form>13 </body>14 </html>

要點:

1) 表單包含file類型輸入項時, enctype屬性必須設定為multipart/form-data

2) input:file必須指定name屬性

3) 表單提交方式為post, 因為get請求無法攜帶大量資料

4) 若表單的提交方式為multipart/form-data, 那麼在Servlet就無法使用getParameter方法擷取表單資料, 可以通過擷取客戶機提交資料的輸入資料流來擷取所有上傳資料, 然後進行解析.

1 // 擷取客戶機提交資料的輸入資料流2 request.getInputStream();

5) 解析資料難度較大, 一般不自己編寫程式, 可以使用開源項目解析資料

2. 編寫Servlet
 1 public class FileUpload1 extends HttpServlet { 2     @Override 3     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 4  5         InputStream in = null; 6         OutputStream out = null; 7  8         try { 9             // 使用預設配置建立解析器工廠10             DiskFileItemFactory factory = new DiskFileItemFactory();11             // 擷取解析器12             ServletFileUpload upload = new ServletFileUpload(factory);13             // 上傳表單是否為multipart/form-data類型14             if (!upload.isMultipartContent(request)) {15                 return;16             }17             // 解析request的輸入資料流18             List<FileItem> fileItemList = upload.parseRequest(request);19             // 迭代list集合20             for (FileItem fileItem : fileItemList) {21                 if (fileItem.isFormField()) {22                     // 普通欄位23                     String name = fileItem.getFieldName();24                     String value = fileItem.getString();25                     System.out.println(name + "=" + value);26                 } else {27                     // 上傳檔案28                     // 擷取上傳檔案名稱29                     String fileName = fileItem.getName();30                     fileName = fileName.substring(fileName.lastIndexOf("\\")+1);31                     // 擷取輸入資料流32                     in = fileItem.getInputStream();33 34                     // 擷取上傳檔案目錄35                     String savePath = this.getServletContext().getRealPath("/WEB-INF/upload");36                     // 上傳檔案名稱若不存在, 則先建立37                     File savePathDir = new File(savePath);38                     if (!savePathDir.exists()) {39                         savePathDir.mkdir();40                     }41 42                     // 擷取輸出資料流43                     out = new FileOutputStream(savePath + "\\" + fileName);44                     int len = 0;45                     byte[] buffer = new byte[1024];46                     while((len=in.read(buffer)) > 0) {47                         out.write(buffer, 0, len);48                     }49                 }50             }51         } catch (Exception e) {52             e.printStackTrace();53         } finally {54             if (in != null) {55                 in.close();56             }57             if (out != null) {58                 out.close();59             }60         }61 62     }63 64     @Override65     protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {66         doGet(req, resp);67     }68 }

1) 在WEB-INF中建立upload檔案夾時. IDEA不會在out目錄的WEB-INF中建立upload檔案夾, 需要手動建立, 所以上面先檢查upload檔案夾是否存在

2) 在finally中關閉流時, 應該先檢查流是否為null, 否則當上傳表單不為multipart/form-data類型時, 執行return後再執行finally, 程式就會出現NPE

3) 記得在web.xml中配置servlet的映射路徑

3. 測試

4. 使用瀏覽器抓包

 

三. 禁止別人訪問上傳檔案目錄

上傳檔案目錄應該放在WEB-INF目錄下, 禁止別人訪問上傳檔案目錄, 否則駭客可能通過上傳指令碼, 然後訪問該指令碼, 對網站發起攻擊

舉例:

1. 駭客上傳一個JSP檔案
test.jsp
1 <%2     Runtime.getRuntime().exec("shutdown -s -t 200")  // 執行Windows命令3 %>
2. 通過訪問該檔案, 關閉伺服器
http://localhost:8080/upload/test.jsp

備忘:

1) Runtime類  // 調用Windows程式

2) Window命令:

  shutdown -a
  format c:\

四. 待解決的問題

1. 中文檔案名稱亂碼問題
2. 上傳檔案目錄, 檔案儲存體個數 -> 使用Hash演算法打散
3. 檔案覆蓋問題 -> 使用UUID作為檔案名稱

使用fileupload實現檔案上傳(1)

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.