jsp 使用者上傳頭像、上傳圖片、郵件上傳附件代碼

來源:互聯網
上載者:User

jsp教程 使用者上傳頭像、上傳圖片、郵件上傳附件代碼


2. 頁面表單的實現
    檔案上傳表單和普通表單有兩個區別

    1) 需要檔案上傳欄位  <input type=”file” />

    2) form 表單的 enctype 屬性需要指定為 multipart/form-data

3. 伺服器端解析request
    在 Servlet 中通過 request.getInputStream 獲得表單上傳資料,會探索資料是分段發送的

由於自己寫程式解析有難度,我們可以使用Apache 開發的開源組件Commons-fileupload

需要匯入 jar 包Commons-fileupload 和Commons-io

4 . UploadServlet 中處理檔案上傳程式
// 1. 建立工廠類

DiskFileItemFactory factory = new DiskFileItemFactory();

// 2. 建立FileUpload對象

ServletFileUpload upload = new ServletFileUpload(factory);

// 3. 判斷是否是上傳表單

boolean b = upload.isMultipartContent(request);

if(!b) {

    // 不是檔案上傳

request.setAttribute("message", "對不起,不是檔案上傳表單!");

request.getRequestDispatcher("/message.jsp").forward(request, response);

    return;

}

// 是檔案上傳表單

// 4. 解析request,獲得FileItem項

List<FileItem> fileitems = upload.parseRequest(request);

// 5. 遍曆集合

for(FileItem item : fileitems) {

    // 判斷是不是普通欄位

if(item.isFormField()) {

    String name = item.getFieldName();

    String value = item.getString();

    // 手工的轉換了

    value = new String(value.getBytes("iso-8859-1"),"utf-8");

    System.out.println(name + "=" + value);

} else {

    // 檔案上傳欄位

    // 獲得檔案名稱

    String filename = item.getName();

    System.out.println(filename);

    filename = filename.substring(filename.lastIndexOf("")+1);

   

    System.out.println(filename);

    // 建立檔案

    ServletContext context = getServletContext();

    String dir = context.getRealPath("WEN-INF/upload");

    File file = new File(dir, filename);

    file.createNewFile();

   

    // 獲得流,讀取資料寫入檔案

    InputStream in = item.getInputStream();

    FileOutputStream fos = new FileOutputStream(file);

   

    int len;

    byte[] buffer = new byte[1024];

    while((len=in.read(buffer))>0)

       fos.write(buffer,0,len);

    fos.close();

    in.close();

    item.delete();    // 刪除臨時檔案

}

二、 檔案上傳處理細節
1. 中文亂碼問題
    1) 檔案名稱中文亂碼問題,解決辦法: 告訴檔案上傳組件以什麼編碼方式來解碼檔案名稱

       ServletUpload.setCharacterEncoding(“utf-8”);

       request. setCharacterEncoding(“utf-8”);

    

    2) 普通欄位中文亂碼問題

       fileitem.getString(“utf-8”);      

2.   臨時檔案
    對於大檔案不能緩衝在記憶體,需要緩衝到硬碟,為了方便管理,我們需要設定臨時檔案存放目錄

    // 設定臨時檔案的存放位置

factory.setRepository(new File("d:/temp"));

    檔案上傳完畢需要刪除臨時檔案,否則會導致伺服器存在兩份上傳檔案

// 注意,需要先將流進行關閉,否則會導致臨時檔案無法刪除

out.close();

in.close();

// 刪除臨時檔案

fileitem.delete();

3. 檔案存放目錄
    1) 目錄需要隱藏,禁止外界直接存取

    2) 檔案名稱需要保證不重複

    3) 檔案應該分目錄存放

三、上傳進度條
1. 實現進度監聽
    需要實現對檔案上傳進度的監聽,需要給FileUpload 對象添加 ProgressListener

    在upload方法中對與進度相關的資料進行處理

    upload.setProgressListener(new ProgressListener() {

    long num = 0;

    public void update(long bytesRead, long contentLength, int items) {

      

            long progress = bytesRead*100/contentLength;

           if(progress==num)

               return;

           num = progress;

           System.out.println("上傳進度:" + progress + "%");

      

        //  request.getSession().setAttribute("progress", progress);

        }

    });

2. 在 jsp 頁面顯示進度
    實驗: 

    1) 使用 iframe 發送請求, 請求一個Servlet, 在Servlet 中返迴響應,發送自增的num

       此時會發現 iframe 會不停第想Servlet發送請求

    2) 點擊檔案上傳按鈕後,iframe立刻停止重新整理,直至上傳完畢頁面跳轉至新頁面

    3)為了觀察實驗結果,將form 的 target 指定為 iframe, UploadServlet回送上傳完畢的結果

    4) 出現上述問題的原因,瀏覽器不支援多線程同時訪問伺服器只能同時發送一個請求,

       這樣的訪問方式為同步訪問

    5) 要在檔案上傳的同時在iframe中實現進度訪問,就需要ie瀏覽器與伺服器進行非同步互動

       此時就需要 XMLHttpRequest 對象

       在網頁特效中可以直接使用XMLHttpRequest 對象與伺服器進行非同步通訊

       獲得XmlHttpRequest 對象的方式有兩種

       ie7以上版本

       var xhr = null;

       if(window.XMLHttpRequest)

           xhr = new XMLHttpRequest();

       ie7以下版本

       if(window.ActiveXObject)

           xhr = new ActiveXObject(“Microsoft.XMLHTTP”);

      

       獲得對象後需要調用open方法輸入請求地址

       注意請求方式, 地址的輸入, 並且需要設定為true 指定非同步訪問該地址

       xhr.open(“get”,”/upload/servlet/UploadServlet”, false)

      

       // 調用send 方法發送請求,post方式需要發送訊息體,get方式則不用直接傳入null值

       xhr.send(null);

      

       // 訪問 responseText 屬性獲得 Servlet 回送的資料

       document.write(xhr.responseText);

四、 api方法
1. DiskFileItemFactory 對象
    設定緩衝區大小,位元組為單位,預設為10K,一般不用修改

    factory.setSizeThreshold(1000);

    設定臨時檔案存放目錄

    factory.setRepository(file);

2. ServletFileUpload 對象
    判斷是否為檔案上傳表單

    boolean b = upload.isMultipartContent(request);

   解析request對象

   List<FileItem> list = upload.parseRequest(request);

   設定上傳檔案的最大值

    setFileSizeMax(long fileSizeMax)

    設定上傳檔案總量的最大值

    setSizeMax(long sizeMax)

    設定編碼格式

    setHeaderEncoding(java.lang.String encoding)

    註冊進度監聽器

    setProgressListener(ProgressListener pListener)

3. FileItem 對象
    獲得表單欄位的屬性名稱

    item.getFieldName();

    獲得普通欄位的值

    item.getString(charsetName)

    獲得檔案上傳欄位的檔案名稱

    item.getName()

    獲得檔案上傳的流

    item.getInputStream()

  

 檔案上傳時需要注意的問題:

1.如何設定上傳檔案最大值,並實現超出最大值時給使用者一個友好提示
 upload.setFileSizeMax(1024*10);  //設定最大值
 實現超出最大值時給使用者一個友好提示:在程式中捕獲FileUploadBase.FileSizeLimitExceededException
 只要程式拋出這個異常,代表使用者上傳的檔案超出最大值
 
 
2.上傳過程中的亂碼問題
 2.1 普通輸入項的亂碼
  item.getString("碼錶 ")
 2.2 上傳檔案名稱的亂碼
  ServletFileUpload.setHeaderEncoding("碼錶")
 
3.上傳檔案的安全性問題
 為防止使用者直接上傳檔案,危害伺服器安全,程式應禁止使用者直接存取上傳檔案(即把上傳檔案儲存在使用者無法直接存取的目錄)
 
4.防止檔案覆蓋(UUID)

5.檔案打散儲存(一個目錄下面不能存超出1000個檔案)
 用hash演算法組建目錄儲存
 
6.設定監聽器,監聽檔案上傳進度

 upload.setProgressListener(new ProgressListener(){
   public void update(long arg0, long arg1, int arg2) {
    System.out.println("當前已上傳" + arg0 + ",當前處理的檔案總大小" + arg1);
   }
  });

7.臨時檔案的刪除問題
 處理完每一個檔案上傳後,一定要記得調用Fileitem.delete方法,刪除臨時檔案
 
8.限定上傳檔案類型
 判斷上傳檔案尾碼名

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.