jsp servlet實現文件上傳

cn55 9年前發布 | 3K 次閱讀 Java

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

/**上傳文件

  • 要求:(1)上傳的文件不能超過文件指定的最大值(2)對有些后綴名的文件不能上傳 / /**Module: Upload.java Description: 上傳文件到指定的目錄(程序和上傳的目錄在同一臺主機)Company: XXX Author: ptpDate: Feb 6, 2012 */ public class Upload extends HttpServlet {

    // 定義常量,保存文件路徑 private static final String FILE_PATH = "D:" + File.separator + "test"

                                         + File.separator + "upload" + File.separator;// 文件上傳的路徑
    
    

    private static final String FILE_TEMP = "D:" + File.separator + "test"

                                         + File.separator + "temp" + File.separator;;// 文件緩存路徑
    
    

    public void doPost (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

     response.setContentType ("text/html; charset=GB2312");
    
     PrintWriter out = response.getWriter();
    
     // ServletFileUpload.isMultipartContent(request);
     // 可以處理之前用上面的方法檢測request中是否有multipart內容,不過,已經是廢棄的方法了
    
     // 生成DiskFileItemFactory工廠
     DiskFileItemFactory factory = new DiskFileItemFactory();
    
     // 對工廠進行相關的配置
     // 設置最多只允許在內存中存儲的數據,單位:字節
     factory.setSizeThreshold (2048);
    
     // 設置一旦文件大小超過getSizeThreshold()的值時數據存放在硬盤的目錄 文件緩存路徑 【暫時沒有實現這個功能】
     //判斷指定的目錄是否存在,如果不存在則新建該目錄,注意mkdirs()和mkdir()的區別:
     //如果test不存在,用mkdir()程序會在后面會報錯,用mkdirs()就不會報錯
     File fileTemp = new File (FILE_TEMP);
     if (!fileTemp.exists() ) {
         fileTemp.mkdirs();
     }
     File filePath1 = new File (FILE_PATH);
     if (!filePath1.exists() ) {
         filePath1.mkdir();//此處可以用mkdir()方法,因為前面的代碼執行后test目錄一定存在
     }
    
     //設置緩存路徑
     factory.setRepository (fileTemp);
    
     // 將DiskFileItemFactory對象傳給ServletFileUpload構造方法,生成上傳類ServletFileUpload的對象
     ServletFileUpload sevletFileUpload = new ServletFileUpload (factory);
    
     // 設置允許用戶上傳文件大小,單位:字節,這里設為2M
     sevletFileUpload.setSizeMax (2 * 1024 * 1024);
    
     // 設置編碼,解決上傳文件名亂碼
     sevletFileUpload.setHeaderEncoding ("GB2312"); /**按照JDK的介紹,此方法是解決上傳文件名中文亂碼問題,但是后面測試發現不能實現*/
    
     //獲得允許用戶上傳文件大小
     long maxSize = sevletFileUpload.getSizeMax();
    
     try {
         /**
          * 開始讀取上傳信息 從request中取到上傳文件列表
          * 超過了設置的最大值2M會報異常
          * 文件緩存目錄不存在也會報異常(前面已經對目錄存在做了判斷,所以不可能出現目錄不存在報的情況)
         */
         List fileItems = sevletFileUpload.parseRequest (request);
         //調用上傳文件的方法
         if (null != fileItems) {
             upLoadFile (fileItems, out);
         }
    
     } catch (FileUploadException e) {
         out.println ("對不起,您上傳的文件大小超過了允許的最大值" + maxSize / 1024 / 1024 + "M!");
         e.printStackTrace();
     }
    

    }

    /**

    • 上傳文件
    • @param fileItems
    • @param out */ public void upLoadFile (List fileItems, PrintWriter out) { try {

       // 依次處理每個上傳的文件
       Iterator iter = fileItems.iterator();
      
       // 正則匹配,過濾路徑取文件名
       /*
        * $ 行的結尾 . 任何字符(與行結束符可能匹配也可能不匹配) + 一次或多次
        * \\\\匹配FILE_PATH中的\\,4個右斜杠轉義后變為2個
       */
       String regExp = ".+\\\\(.+)$";
      
       // 過濾掉的文件類型
       String[] errorType = { ".exe", ".com", ".cgi", ".asp" };
      
       StringBuffer error = new StringBuffer();
      
       //拼接不能上傳的文件類型,即字符串error,用于后面顯示
       for (int i = 0; i < errorType.length; i++) {
           if (i == errorType.length - 1) {
               error.append (errorType[i] + "。");
           } else {
               error.append (errorType[i] + ",");
           }
       }
      
       Pattern p = Pattern.compile (regExp); //將給定的正則表達式regExp編譯到模式中
       while (iter.hasNext() ) {
           FileItem item = (FileItem) iter.next();
           /*忽略其他不是文件域的所有表單信息
           *isFormField()方法判斷FileItem類對象封裝的數據是否屬于一個普通表單字段,
           *還是屬于一個文件表單字段,如果是普通表單字段則返回true,否則返回false
           *只有是文件表單字段才能進入if中的代碼
           */
           if (!item.isFormField() ) {
               String name = item.getName();// 用于獲得上傳文件的名稱,如:c:\documents and settings\administrator\桌面\test.txt
               long size = item.getSize();// 獲得上傳文件的大小
               if ( (name == null || name.equals ("") ) && size == 0) { // 文件表單為空或文件大小為0跳過本次循環,繼續下一次循環
                   continue;
               }
               Matcher m = p.matcher (name); // 創建匹配給定輸入與此模式的匹配器
               boolean result = m.find();// 方法掃描輸入序列以查找與該模式匹配的下一個子序列
               if (result) {
                   for (int temp = 0; temp < errorType.length; temp++) {
                       if (m.group (1).endsWith (errorType[temp]) ) {
                           throw new IOException ("非法文件類型禁止上傳,以下文件類型不能上傳:" + error);
                       }
                   }
                   try {
      
                       //保存上傳的文件到指定的目錄
                       File filePath = new File (FILE_PATH + m.group (1) );
                       item.write (filePath);
      
                       //在頁面上輸出上傳文件后的信息
                       out.print (name + "&nbsp;&nbsp;" + size + "<br>");
      
                   } catch (Exception e) {
                       out.println (e);
                   }
               } else {
                   throw new IOException ("上傳文件失敗");
               }
           }
       }
      

      } catch (IOException e) {

       out.println (e);
      

      } }

      public void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost (request, response); } }</pre>

 本文由用戶 cn55 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!