JavaWeb(十三)-檔案上傳
阿新 • • 發佈:2018-12-26
一、檔案上傳
1-1:客戶端程式設計
<!DOCTYPE html> <html> <head> <title></title> </head> <body> /* 單檔案上傳*/ <form action="/sss" method="post" enctype="multipart/form-data"> <input type="file" name="fieldName"> <input type="submit" value="上dfa傳"> </form> <br /> /*多檔案上傳*/ <form action="/sss" method="post" enctype="multipart/form-data"> <input type="file" name="fieldName" multiple /> <input type="file" name="fieldName" multiple="df" /> <input type="file" name="fieldName" multiple="" /> <input type="submit" value="上傳"> </form> </body> <script type="text/javascript"> </script> </html>
關於前端表單
- 每個表單項為一個部件
- 一個部件中自己包含請求頭與空行
- 關於content-disposition
- 非檔案域
- 檔案域
- 非檔案域
1-2:伺服器端程式設計
在Servlet3.0中已經不需要匯入Commons-FileUpload了
-
用於處理檔案上傳的Servlet必須用@MultipartConfig進行標註。其屬性如下:
- maxFileSize 最大支援上傳大小; -1為不受限制
- maxRequestSize 執行多部分HTTP請求的最大容量
- location 將上傳的檔案儲存到磁碟的指定位置
- fileSizeThreshold 設定一個溢位尺寸,超出這個值,上傳的檔案被寫入磁碟。
- HTTPServletRequest中,一個由多部分組成的請求中,每一個表單域,包括非檔案域,都會被轉換成Part。
借用網上某位大神的例子:
package me.gacl.web.controller; import java.io.File; import java.io.IOException; import java.io.PrintWriter; import java.util.Collection; import javax.servlet.ServletException; import javax.servlet.annotation.MultipartConfig; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.Part; //使用@WebServlet配置UploadServlet的訪問路徑 @WebServlet(name="UploadServlet",urlPatterns="/UploadServlet") //使用註解@MultipartConfig將一個Servlet標識為支援檔案上傳 @MultipartConfig//標識Servlet支援檔案上傳 public class UploadServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8"); response.setCharacterEncoding("utf-8"); response.setContentType("text/html;charset=utf-8"); //儲存路徑 String savePath = request.getServletContext().getRealPath("/WEB-INF/uploadFile"); //獲取上傳的檔案集合 Collection<Part> parts = request.getParts(); //上傳單個檔案 if (parts.size()==1) { //Servlet3.0將multipart/form-data的POST請求封裝成Part,通過Part對上傳的檔案進行操作。 //Part part = parts[0];//從上傳的檔案集合中獲取Part物件 Part part = request.getPart("file");//通過表單file控制元件(<input type="file" name="file">)的名字直接獲取Part物件 //Servlet3沒有提供直接獲取檔名的方法,需要從請求頭中解析出來 //獲取請求頭,請求頭的格式:form-data; name="file"; filename="snmp4j--api.zip" String header = part.getHeader("content-disposition"); //獲取檔名 String fileName = getFileName(header); //把檔案寫到指定路徑 part.write(savePath+File.separator+fileName); }else { //一次性上傳多個檔案 for (Part part : parts) {//迴圈處理上傳的檔案 //獲取請求頭,請求頭的格式:form-data; name="file"; filename="snmp4j--api.zip" String header = part.getHeader("content-disposition"); //獲取檔名 String fileName = getFileName(header); //把檔案寫到指定路徑 part.write(savePath+File.separator+fileName); } } PrintWriter out = response.getWriter(); out.println("上傳成功"); out.flush(); out.close(); } /** * 根據請求頭解析出檔名 * 請求頭的格式:火狐和google瀏覽器下:form-data; name="file"; filename="snmp4j--api.zip" * IE瀏覽器下:form-data; name="file"; filename="E:\snmp4j--api.zip" * @param header 請求頭 * @return 檔名 */ public String getFileName(String header) { /** * String[] tempArr1 = header.split(";");程式碼執行完之後,在不同的瀏覽器下,tempArr1數組裡面的內容稍有區別 * 火狐或者google瀏覽器下:tempArr1={form-data,name="file",filename="snmp4j--api.zip"} * IE瀏覽器下:tempArr1={form-data,name="file",filename="E:\snmp4j--api.zip"} */ String[] tempArr1 = header.split(";"); /** *火狐或者google瀏覽器下:tempArr2={filename,"snmp4j--api.zip"} *IE瀏覽器下:tempArr2={filename,"E:\snmp4j--api.zip"} */ String[] tempArr2 = tempArr1[2].split("="); //獲取檔名,相容各種瀏覽器的寫法 String fileName = tempArr2[1].substring(tempArr2[1].lastIndexOf("\\")+1).replaceAll("\"", ""); return fileName; } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doGet(request, response); } }
總結:
檔案上傳之細節
- 檔案必須儲存在WEB-INF下
- 若是一個檔案表單項,則request.getParameter("xxx")返回為null
- 利用UUID解決檔案重名問題
- 上傳檔名是絕對路徑需要拆分
- req.setCharacterEncoding("UTF-8")
- 目錄打散
- 首字母打散:使用檔案首字母作為目錄名稱
- 時間打散:使用當前時間作為目錄
- 雜湊打散 通過檔名稱獲得整型 (hashcode());10進位制轉換為16進位制,用16進位制,前兩層作為目錄