JAVA文件上傳 ServletFileUpLoad 實例

1.  jsphtml

 1 <%@ page language="java" contentType="text/html" pageEncoding="utf-8"%>
 2 <!DOCTYPE html>
 3 <html>
 4 <head>
 5 <title>文件上傳</title>
 6 </head>
 7 <body>
 8     <form action="FileUploadServlet" method="post" enctype="multipart/form-data">
 9         用戶名:<input type="text" name="name"><br>
10         文件1:<input type="file" name="f1"><br>
11         文件2:<input type="file" name="f2"><br>
12         <input type="submit" value="提交">
13     </form>
14     
15 </body>
16 </html>

2.  java  java

文件上傳的前提
 1.form表單的method必須是post
 2.form表單的enctype必須是multipart/form-data 以二進制字節流
 進行提交 傳統接收參數的方式無效
 DiskFileItemFactory:環境
     void setSizeThreshold(int sizeThreshold)
     設置緩衝區大小,默認10KB 超出將使用臨時文件上傳
     void setRepository(File repository)
     設置臨時文件路徑
 ServletFileUpload:核心操做類
     public void setSizeMax(long sizeMax)設置總文件的大小
     public void setFileSizeMax(long fileSizeMax):設置單個文件的大小
     public List parseRequest(javax.servlet.http.HttpServletRequest req)
     解析請求正文內容
     public static boolean isMultipartContent(HttpServletRequest req)//判斷enctype
 FileItem:輸入域
     boolean  isFormField():判斷是不是普通字段
     String getName():獲取上傳文件名
     String getFieldName():獲取普通字段的字段名
     String getString():獲取普通字段的值
     String getContentType() 得到文件類型
     InputStream  getInputStream()以流的形式返回上傳文件的主體內容
     void  delete()刪除臨時文件
 文件上傳中須要注意的問題
    1.保證安全 
        上傳文件放在WEB-INF目錄中
    2.中文亂碼問題
        普通字段亂碼
        String fieldValue = item.getString("GBK");
          文件名亂碼
          request.setCharacterEncoding("GBK");
      3.重名文件覆蓋
          1.UUID
          2.使用文件上傳日期分類存儲
          3.System.currentMillions()
      4.限制文件上傳類型
         1.endsWith("")這種方式不可取
         2.判斷其mime類型 getContentType()
      5.限制用戶上傳文件的大小
          1.限制單個上傳文件的大小
          upload.setFileSizeMax(4*1024*1024);
          2.限制總文件大小
        upload.setSizeMax()
     6.臨時文件
         item.delete();
     7.多個文件上傳時,沒有上傳內容的問題
         if(fileName==null||"".equals(fileName.trim())){
                        continue;
        }
     8.上傳進度檢測
            upload.setProgressListener(new ProgressListener(){
                參數一:已上傳的字節數
                參數二:總字節數
                參數三:第幾項
                @Override
                public void update(long arg0, long arg1, int arg2) {
                    // TODO Auto-generated method stub
                    System.out.println(arg0+"  "+arg1+"  "+arg2);
                }
                
            });

 

  1 package cn.gs.ly;
  2 
  3 import java.io.File;
  4 import java.io.FileOutputStream;
  5 import java.io.IOException;
  6 import java.io.InputStream;
  7 import java.io.OutputStream;
  8 import java.util.List;
  9 
 10 import javax.servlet.ServletException;
 11 import javax.servlet.http.HttpServlet;
 12 import javax.servlet.http.HttpServletRequest;
 13 import javax.servlet.http.HttpServletResponse;
 14 
 15 import org.apache.commons.fileupload.FileItem;
 16 import org.apache.commons.fileupload.FileUploadException;
 17 import org.apache.commons.fileupload.ProgressListener;
 18 import org.apache.commons.fileupload.disk.DiskFileItemFactory;
 19 import org.apache.commons.fileupload.servlet.ServletFileUpload;
 20 
 21 
 22 public class FileUploadServlet extends HttpServlet {
 23     @Override
 24     protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
 25         try {
 26         //獲得上傳文件的保存目錄。 將上傳的文件存放於WEB-INF目錄下,不容許外界直接訪問,保證上傳文件的安全
 27         String realPath = this.getServletContext().getRealPath("/upload");//  /WEB-INF/files
 28         System.out.println("文件存放位置:"+realPath);
 29         //設置臨時目錄。 上傳文件大於緩衝區則先放於臨時目錄中
 30         String tempPath = "E:\\tempPath";
 31         System.out.println("臨時文件存放位置:"+tempPath);
 32         
 33         
 34         //判斷存放上傳文件的目錄是否存在(不存在則建立)
 35         File f = new File(realPath);
 36             if(!f.exists()&&!f.isDirectory()){
 37                 System.out.println("目錄或文件不存在! 建立目標目錄。");
 38                 f.mkdir();
 39             }
 40         //判斷臨時目錄是否存在(不存在則建立)
 41         File f1 = new File(tempPath);
 42             if(!f1.isDirectory()){
 43                 System.out.println("臨時文件目錄不存在! 建立臨時文件目錄");
 44                 f1.mkdir();
 45             }
 46         
 47        /**
 48         * 使用Apache文件上傳組件處理文件上傳步驟:
 49         * 
 50         * */
 51         //一、設置環境:建立一個DiskFileItemFactory工廠    
 52         DiskFileItemFactory factory = new DiskFileItemFactory();
 53         
 54             //設置上傳文件的臨時目錄
 55         factory.setRepository(f1); 
 56         
 57         //二、核心操做類:建立一個文件上傳解析器。
 58         ServletFileUpload upload = new ServletFileUpload(factory);
 59             //解決上傳"文件名"的中文亂碼
 60         upload.setHeaderEncoding("UTF-8");
 61         
 62         //三、判斷enctype:判斷提交上來的數據是不是上傳表單的數據
 63         if(!ServletFileUpload.isMultipartContent(req)){
 64             System.out.println("不是上傳文件,終止");
 65              //按照傳統方式獲取數據
 66             return;
 67         }
 68         
 69         //==獲取輸入項==
 70 //            //限制單個上傳文件大小(5M)
 71 //            upload.setFileSizeMax(1024*1024*4);
 72 //            //限制總上傳文件大小(10M)
 73 //            upload.setSizeMax(1024*1024*6);
 74         
 75         //四、使用ServletFileUpload解析器解析上傳數據,解析結果返回的是一個List<FileItem>集合,每個FileItem對應一個Form表單的輸入項
 76             List<FileItem> items =upload.parseRequest(req);
 77             for(FileItem item:items){
 78                 //若是fileitem中封裝的是普通輸入項的數據(輸出名、值)
 79                 if(item.isFormField()){
 80                     String filedName = item.getFieldName();//普通輸入項數據的名
 81                     //解決普通輸入項的數據的中文亂碼問題
 82                     String filedValue = item.getString("UTF-8");//普通輸入項的值
 83                     System.out.println("普通字段:"+filedName+"=="+filedValue);
 84                 }else{
 85                     //若是fileitem中封裝的是上傳文件,獲得上傳的文件名稱,        
 86                     String fileName = item.getName();//上傳文件的名
 87                     //多個文件上傳輸入框有空 的 異常處理
 88                     if(fileName==null||"".equals(fileName.trim())){  //去空格是否爲空
 89                         continue;// 爲空,跳過當次循環,  第一個沒輸入則跳過能夠繼續輸入第二個
 90                     }
 91                     
 92                     //注意:不一樣的瀏覽器提交的文件名是不同的,有些瀏覽器提交上來的文件名是帶有路徑的,如:  c:\a\b\1.txt,而有些只是單純的文件名,如:1.txt
 93                     //處理上傳文件的文件名的路徑,截取字符串只保留文件名部分。//截取留最後一個"\"以後,+1截取向右移一位("\a.txt"-->"a.txt")
 94                     fileName = fileName.substring(fileName.lastIndexOf("\\")+1);
 95                     //拼接上傳路徑。存放路徑+上傳的文件名
 96                     String filePath = realPath+"\\"+fileName;
 97                     //構建輸入輸出流
 98                     InputStream in = item.getInputStream(); //獲取item中的上傳文件的輸入流 
 99                     OutputStream out = new FileOutputStream(filePath); //建立一個文件輸出流
100                     
101                     //建立一個緩衝區
102                     byte b[] = new byte[1024];
103                     //判斷輸入流中的數據是否已經讀完的標識
104                     int len = -1;
105                      //循環將輸入流讀入到緩衝區當中,(len=in.read(buffer))!=-1就表示in裏面還有數據
106                     while((len=in.read(b))!=-1){  //沒數據了返回-1
107                     //使用FileOutputStream輸出流將緩衝區的數據寫入到指定的目錄(savePath+"\\"+filename)當中
108                         out.write(b, 0, len);
109                     }
110                     //關閉流
111                     out.close();
112                     in.close();
113                     //刪除臨時文件
114                     try {
115                         Thread.sleep(3000);
116                     } catch (InterruptedException e) {
117                         e.printStackTrace();
118                     }
119                     item.delete();//刪除處理文件上傳時生成的臨時文件
120                     System.out.println("文件上傳成功");
121                 }    
122             }    
123         } catch (FileUploadException e) {
124             //e.printStackTrace();
125             throw new RuntimeException("服務器繁忙,文件上傳失敗");
126         }    
127     }
128     
129     @Override
130     protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
131         this.doPost(req, resp);
132     }
相關文章
相關標籤/搜索