1. 程式人生 > >servlet3.0實現檔案上傳

servlet3.0實現檔案上傳

servlet3.0實現檔案上傳功能

必須使用tomcat7以上的技術才能支援servlet3.0
servlet3.0 比 servlet2.5 多提供了三個新特性:
  註解開發:方便
  檔案上傳:有些api不是特別全
  非同步請求:基本不用,使用ajax替代

檔案上傳技術:

1.servlet3.0
2.JSPSmartUpload 嵌入到JSP中完成檔案上傳,主要用於model1年代
3.FileUpload Apache的檔案上傳的元件。
4.Struts2 底層是FileUpload。
。。。

檔案上傳的三要素:

  1.表單的提交方式必須是post,因為get有大小限制;
  2.表單中需要有檔案上傳的表單元素:<input type= "file" name="upload">這個元素必須要有name屬性和值;
  3.表單的enctype屬性的值必須是multipart/form-data

使用註解代替web.xml

  使用註解配置servlet

    @WebServlet(urlPatterns="/ServletName",loadOnStartup=2,initParams={@WebInitParam(name="username",value=""),@WebInitParam(name="password",value="")})

  使用註解開發Listener:
    @WebListener
  使用註解開發Filter;
    @WebFilter(urlPatterns="/*")

注意:
當沒有設定enctype屬性的時候,只能獲得檔案的名稱,沒有檔案內容;
設定enctype屬性為multipart/form-data後可以獲得檔名及檔案內容;

使用servlet3.0實現檔案上傳:
  在建立servlet的時候需要額外加一個註解@MultipartConfig,否則3.0的request的提供的新的方法無法使用。

使用servlet3.0註解技術實現檔案上傳程式碼示例

 

 1 <html>
 2 <head>
 3 <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
 4 <title>Hello Miss Dang</title>
 5 </head>
 6 <body>
 7     <h1>index.jsp</h1>
 8     <form action="${pageContext.request.contextPath}/UploadServlet" method="post" enctype="multipart/form-data">
 9         檔案描述<input  type="text" name="filedesc" /><br/>
10         請選擇需要上傳的檔案:<input type="file" name="upload" />
11         <input type="submit" value="上傳" />
12     </form>
13 </body>
14 </html>

前端表單上傳檔案程式碼示例

 1 package 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 @WebServlet("/UploadServlet")
17 @MultipartConfig
18 public class UploadServlet extends HttpServlet {
19     
20     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
21         doPost(request, response);
22     }
23 
24     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
25         request.setCharacterEncoding("UTF-8");
26         System.out.println("檔案描述:"+request.getParameter("filedesc"));
27         Part part = request.getPart("upload");
28         System.out.println("檔案大小:"+part.getSize());
29         System.out.println("form表單中part部分的name屬性名稱"+part.getName());
30         //獲得上傳的檔名稱
31         String header = part.getHeader("Content-Disposition");//獲得Content-Disposition的頭資訊
32         int idx = header.lastIndexOf("filename=\"");//獲取filename=“字串的開始下標
33         String fileName = header.substring(idx+"filename=\"".length(), header.length()-1);
34         System.out.println("檔名:"+fileName);
35         //獲得檔案內容:
36         InputStream is = part.getInputStream();
37         OutputStream os = new FileOutputStream(this.getServletContext().getRealPath("/upload")+"/"+fileName);
38         byte[] bt = new byte[1024];
39         int len = 0;
40         while ((len = is.read(bt)) != -1) {
41             os.write(bt, 0, len);
42         }
43         is.close();
44         os.close();
45     }
46 
47 }

後端servlet程式碼示例

 檔案上傳問題:檔名重名

使用隨機的唯一檔名:
使用uuid作為隨機檔名
UUID。randomUUID().toString().replace("_","")+"_"+fileName;

檔案上傳問題:資料夾問題(一個目錄下存放檔案過多)

一個目錄下檔案過多,導致開啟都很慢,更別說讀寫操作更慢,影響效能。

目錄分離:
  按時間分:按周 按月分(按訪問量來劃分)
  按數量分:一個目錄下存放n個檔案,如果滿了就建立新的目錄存放。
  按使用者分;
  按目錄分離演算法分:
    使用唯一檔名.hashCode();--得到一個代表當前這個檔案的int型別的值,int型別佔4個位元組32位,可以讓hashCode值&0xf;(oxf是十六進位制數,代表15,記憶體中表示是1111),得到一個int值,可以用這個int值作為一級目錄,讓這個hashCode右移4位&0xf;得到一個int值,用這個int值作為二級目錄,以此類推。

 

1 public static String getFilePath(String fileName) {
2         int code1 = fileName.hashCode();
3         int d1 = code1 & 0xf;//獲得一級目錄
4         int code2 = code1 >>> 4;
5         int d2 = code2 & 0xf;//獲得二級目錄
6         //可以根據自己的需求獲得多級目錄。
7         return "/"+d1+"/"+d2;
8     }

判斷資料夾是否存在,如果不存在建立

File file = new File(path);
if(!file.exits()){
  file.mkdirs();
}