JavaWeb開發之網站實現文件上傳功能


   轉載請注明原文地址:http://www.cnblogs.com/ygj0930/p/6073505.html 

    一個功能完善的JavaWeb應用,必不可少的一個功能就是文件的上傳。無論是用戶的頭像等,還是用戶需要上傳的一系列資料,都是通過文件的上傳功能實現的。

    目前我們實現網站中關於文件的上傳功能時,常用的是apache的開源工具common-fileupload以及common-fileupload的依賴包common-io。

    下面以一個注冊頁面的后台程序為例,大致講解這兩個包的使用:

    首先,前往apache官網上面下載common-fileupload、common-io這兩個包,並放入工程的WEB-INF文件夾的lib目錄下。

    然后,在網站頁面的表單那里設置:

  文件選擇按鈕為:<input type="file"/>

  表單數據屬性設置為:enctype="multipart/form-data"。因為只有使用enctype="multipart/form-data",表單才會把文件的內容編碼到HTML請求中。

  原理請移步:http://blog.csdn.net/mazhibinit/article/details/49667511 進行了解。

<form action="upload_do.jsp" method="post" enctype="multipart/form-data">    
   文件上傳欄: <input type="file" size="30" name="upload" />
   <input type="submit" value="提交上傳" />    
 </form>

 

    最后,在表單提交的目的jsp文件中使用兩個包中的工具類進行文件的提取與保存,一般步驟如下:

    1、實例化一個硬盤文件工廠,用來配置上傳組件ServletFileUpload的一些基本設定。比如

    DiskFileItemFactory dfif = new DiskFileItemFactory();
 // 定義文件上傳時的“運輸船”大小。文件是一部分一部分上傳的,這里設置為4K。當數據讀取到4K則寫入硬盤的臨時文件夾中,清空運輸船繼續讀取。
//文件傳輸完后,再從臨時文件夾轉存到實際的保存路徑下
dfif.setSizeThreshold(4096);
// 設置存放臨時文件的目錄如下:獲取完整路徑——修改路徑新建臨時文件夾——把臨時文件夾設為工廠的默認目錄(則工廠獲取的內容會默認存放在這里) String realwebbase = request.getSession().getServletContext().getRealPath("/"); File temp_file = new File(realwebbase+"upload/UploadTemp"); if (!temp_file.exists()) { temp_file.mkdirs(); }
dfif.setRepository(temp_file);

    2、用工廠實例化上傳組件,則該組件會使用該工廠實例的一系列配置(如:以多大容量為一次上傳文件、臨時文件存放處等)

    ServletFileUpload sfu = new ServletFileUpload(dfif);
    sfu.setHeaderEncoding("UTF-8");
    // 設置上傳文件的最大容量
    sfu.setSizeMax(MAX_SIZE);

    3、從request對象中把上傳內容提取到一個list中。從上面引用的博文處可以看到,POST+multipart/form-data的效果是form表單內的內容以鍵值對的形式提交上去。

    List fileList = null;
    try {
        fileList = sfu.parseRequest(request);
    } 
    catch (FileUploadException e) { }

    4、用迭代器遍歷list對象,提取上傳內容。上傳內容主要分兩種:文本與非文本內容(圖片、多媒體文件等)

    Iterator fileItr = fileList.iterator();
    while (fileItr.hasNext()) {            
        FileItem fileItem = (FileItem) fileItr.next();
        if(fileItem.isFormField()){ //第一種上傳內容:普通文本,分別獲取鍵名、值內容即可                   
            String name = fileItem.getFieldName();        //獲取鍵值對的鍵名
            String value = fileItem.getString("UTF-8");   //此處的getString()是指對list的當前元素(鍵值對)的值,按照參數所指定的解碼方式進行解析、獲取內容
        }else{ //第二種上傳內容:非文本,則需要用到流傳輸來把內容讀取、保存到具體的路徑下
            String path = fileItem.getName();  //獲取文件的路徑名,用於截取擴展名進行文件類型的判斷// 得到文件的大小,用於判斷文件大小是否合法
            long size = fileItem.getSize();
            if ("".equals(path) || size == 0) {
                out.println("上傳的文件無效!");
                out.close();
                return;
            }        
            // 得到去除路徑的文件名
            String t_name = path.substring(path.lastIndexOf("/") + 1);
            // 得到文件的擴展名(無擴展名時將得到全名)
            String t_ext = t_name.substring(t_name.lastIndexOf(".") + 1);
            
          
//遍歷允許的擴展名數組,看看上傳文件的擴展名是否合法。 int i = 0;
       boolean errorflag=true;
while (i < allowedExt.length) { if (allowedExt[i].equals(t_ext)){
            errorflag=false;
break; } i=i+1; } if (errorflag) { out.println("請上傳合法文件!"); out.close(); return; }
            // 用uuid+日期作為文件名的一部分來唯一標識文件
            String uuid = UUID.randomUUID().toString(); 
            String today = new SimpleDateFormat("yyyyMMdd").format(new Date());
            //生成最終的文件保存完整路徑:目錄路徑+日期+UUID+ . +擴展名
            String u_name = realwebbase + "upload/" + today + "/" + uuid + "." + t_ext;
            
try { File _today_file = new File(realwebbase + "upload/Uploaded/" + _today); //構建文件目錄 if (!_today_file.exists()) { _today_file.mkdirs(); } fileItem.write(new File(u_name)); //把當前list元素的值用write流寫到創建好的路徑下,即實現文件內容的保存了return; } catch (Exception e) { e.printStackTrace(); } }

     5、最后,就是把文件的相對路徑信息保存到數據庫中去,使文件得以在其他文件中通過相對路徑進行引用了。

 

    


免責聲明!

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



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