JAVA文件上傳 ServletFileUpLoad 實例


1.  jsp

 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  

文件上傳的前提
 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         //1、設置環境:創建一個DiskFileItemFactory工廠    
 52         DiskFileItemFactory factory = new DiskFileItemFactory();
 53         
 54             //設置上傳文件的臨時目錄
 55         factory.setRepository(f1); 
 56         
 57         //2、核心操作類:創建一個文件上傳解析器。
 58         ServletFileUpload upload = new ServletFileUpload(factory);
 59             //解決上傳"文件名"的中文亂碼
 60         upload.setHeaderEncoding("UTF-8");
 61         
 62         //3、判斷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         //4、使用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     }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM