Dashboard > JAVA EE > ... > JSF應用 > 在 JSF 實作檔案上傳
JAVA EE Log In   View a printable version of the current page.
在 JSF 實作檔案上傳
Added by cheetah, last edited by cheetah on May 20, 2005  (view change)
Labels: 
(None)

資料來源: Servlet/JSP 討論區
作者: CMHuang

  目前 JSF 對於檔案上傳的支援很差,JSC 內更是缺少檔案上傳的元件

  除非使用 Orcale ADF 的元件,但是 Oracle ADF 並非免費的。

  本篇文章主要就是跟大家分享如何在 JSF 內使用免費的 Jakarta Commons FileUpload (http://jakarta.apache.org/commons/fileupload/) 元件來實作檔案上傳功能。

  有幾點注意事項,這邊必須先要提出的:

 1. Servlet 部分改自本討論區 JiaYun 大大的「檔案上傳 JSP 小範例」,希望他不會介意!^^" (如果需要更清楚的 Jakarta Commons FileUpload 範例,那篇文章會是更好的選擇。)

 2. 檔案上傳,必須把 form 的 enctype 更改如下:

<h:form binding="#{AttachFile.form1}" enctype="multipart/form-data" id="form1">

  但是以上的 JSF 標籤 compile 都會正常,但是在這個 form 裡面,其他元件的 action 都會無法正常觸發。所以這邊僅使用一般的 JSP 頁面。

 3. 這篇獻醜的教學其實是使用 JSF(其他頁面) -> JSP(選擇檔案頁面) -> Servlet(儲存使用者上傳的檔案) -> JSF(其他頁面) 的流程。
說穿了,只是使用舊的 JSP + Servlet 技術,請各位高手海涵。


 流程一(選擇檔案的 JSP 頁面):

<f:verbatim>
  <form action="UploadFile" enctype="multipart/form-data" method="post">
    File:<input name="txtFile" type="file"/><br/>                        
    Description:<input name="txtDesc" type="text"/><br/>
    <input type="checkbox" name="chkAdd"/>Add another file<br/>
    <input style="height: 27px; left: 0px; top: 96px; position: absolute; width: 72px" type="submit" value="Add"/>
    <input style="height: 27px; left: 96px; top: 96px; position: absolute; width: 72px" type="submit" value="Cancel"/>
  </form>
</f:verbatim>                
<h:form binding="#{AttachFile.form1}" id="form1"/>

 1. 這個頁面包含:

  一個 type="file" 的 textbox

  一個一般的 textbox 提供為輸入檔案描述

  一個 checkbox,提供多重上傳檔案

  一個 Add 及一個 Cancel 的 Button

 2. 如果使用者選取 checkBox,在後面的 Servlet 處理完,則回到這一頁 ,選擇另一個上傳的檔案。 如果沒有勾選,則前進到其他的 JSF 頁面。

 3. UploadFile 為後面要處理檔案儲存的 Servlet 名稱。

 4. 以上只寫出修改的地方,其他 JSF 預設的 tag 就不寫出來了。


 流程二(web.xml):

<servlet>
  <servlet-name>Upload_File</servlet-name>
  <servlet-class>webapplication1.UploadFile</servlet-class>
</servlet>
<servlet-mapping>
  <servlet-name>Upload_File</servlet-name>
  <url-pattern>/UploadFile</url-pattern>
</servlet-mapping>

 1. 請把這一段程式碼與 web.xml 內的其他 servlet tag 放在一塊,比較不會出問題。

 2. 這段大致的意義為:當你向 server 要求 /UploadFile 這個 URL 時, server 會使用 webapplication1.UploadFile 這個 servlet 來處理你的要求。


 流程三(後端處理檔案的 Servlet):

UploadFile
import java.io.*;
import java.util.*;
import java.sql.*;
import javax.servlet.*;
import javax.servlet.http.*;
import org.apache.commons.fileupload.*;

public class UploadFile extends HttpServlet{
    public void doPost(HttpServletRequest servletRequest, HttpServletResponse servletResponse) throws ServletException, IOException {
      //取得 JSF 的 SessionBean
      SessionBean1 sesBean=(SessionBean1)servletRequest.getSession().getAttribute("SessionBean1");
      //取得 JSF 的 ApplicationBean
      ApplicationBean1 appBean=(ApplicationBean1)getServletContext().getAttribute("ApplicationBean1");
      // 宣告將上傳之檔案放置到伺服器的 / .... /upload 目錄中
      //String saveDirectory = appBean.getAttachPath();
      // 宣告暫存目錄
      //String tmpDirectory = "c:\\";
      // 宣告限制上傳之檔案總大小為, 單位為 byte, -1 表示無限制
      int maxPostSize = -1;
      // 宣告儲存敘述上傳檔案內容的變數
      String FileDescription = "";
      // 宣告是否接下來要繼續新增檔案
      boolean hasMore = false;
      // 宣告儲存上傳檔案名稱的變數
      String FileName = "";
      // 宣告儲存上傳檔案大小的變數
      long FileSize = 0;
      // 宣告儲存上傳檔案型態的變數
      //String ContentType = null;
      // 計算上傳檔案之個數
      int count = 0 ;

      try {
        DiskFileUpload upload = new DiskFileUpload();
        // 處理中文檔名問題
        upload.setHeaderEncoding("UTF-8"); 
        // 設定記憶體存放資料的大小, 超過則寫入檔案, 有設定暫存目錄, 暫存檔置於暫存目錄下
        //upload.setSizeThreshold(4096);
        // 設定總上傳大小限制
        //upload.setSizeMax(maxPostSize);
        // 設定暫存目錄
        //upload.setRepositoryPath(tmpDirectory);
        List items =upload.parseRequest((HttpServletRequest)servletRequest);
        Iterator iter = items.iterator();
        FileItem fItem=null;
        
        while(iter.hasNext()) {
                FileItem item = (FileItem) iter.next();
                if (item.isFormField()) {
                    // 一般欄位
                    if(item.getFieldName().equalsIgnoreCase("txtDesc")) {
                        // 取得檔案敘述
                        FileDescription = item.getString("UTF-8");
                    }
                    else if(item.getFieldName().equalsIgnoreCase("chkAdd")) {
                        // 取得接下來將前往的頁面
                        hasMore = item.getString().equalsIgnoreCase("on") ? true: false;
                    }
                }
                else {
                    // 檔案欄位
                    // 否則取得檔案資訊
                    FileName = item.getName();
                    // 因為不同的瀏覽器會造成傳遞 path + filename, 有些則只有 filename
                    // for wintel platform
                    FileName = FileName.substring(FileName.lastIndexOf("\\")+1);
                    // for unix-like platform
                    FileName = FileName.substring(FileName.lastIndexOf("/")+1);
                    
                    //ContentType = item.getContentType();
                    FileSize = item.getSize();                    
                    
                    fItem=item;
                }
            }

            //--Delete--
            //如果需要的話
            //你可以在這裡使用前面取得的 SessionBean 及 ApplicationBean
            //裡面的參數對你的資料庫做操作,並把檔案描述在這裡存入資料庫
            
            //寫入檔案 
            File uploadedFile = new File(appBean.getAttachPath() + FileName);
            fItem.write(uploadedFile);            
        }
        catch(Exception ex) {
          //例外處理            
        }
        //導向不同的頁面
        finally {
            if(hasMore)
                servletResponse.sendRedirect("faces/AttachFile.jsp");
            else
                servletResponse.sendRedirect("faces/Schedule.jsp");
        }
    }
}

 1. 前面的取得 SessionBean1 及 ApplicationBean1,看個人需要,如果你需要取得 JSF 內的 SessionBean 及 ApplicationBean,可以參考這個用法。

 2. 最後的 servletResponse.sendRedirect 會根據前面的 JSP 頁面,是否有勾選 chkAdd 來決定是要回到前面的 JSP 頁面來繼續新增檔案,或是前往其他 JSF 頁面。

 3. 請注意 faces/Schedule.jsp 前面的 faces ,如果不加可能可會出現 Cannot find FacesContext 的錯誤。

Site powered by a free Open Source Project / Non-profit License (more) of Confluence - the Enterprise wiki.
Learn more or evaluate Confluence for your organisation.
Powered by Atlassian Confluence, the Enterprise Wiki. (Version: 2.1.5a Build:#411 Mar 16, 2006) - Bug/feature request - Contact Administrators