itVincent Blog - Java Working Fun!

          技術(shù)引領(lǐng)時(shí)代!
          posts - 117, comments - 181, trackbacks - 0, articles - 12

          [轉(zhuǎn)]用JSF和MyFaces上傳文件

          Posted on 2006-11-01 14:25 itVincent 閱讀(1983) 評(píng)論(4)  編輯  收藏 所屬分類: JSF

          用JSF和MyFaces上傳文件

          RR00 發(fā)表于 2005-08-31 00:12:00
          作者:Andrei Cioroianu;RR00???? 來源:Onjava
          評(píng)論數(shù):1 點(diǎn)擊數(shù):4,703???? 投票總得分:5 投票總?cè)舜?1
          關(guān)鍵字:JSF MyFaces Upload

          摘要:

          用戶可以很方便使用瀏覽器上傳文件,但是當(dāng)前的Java Web標(biāo)準(zhǔn)(如servlets, JSP, and JSF)并沒有提供任何上傳的功能。幸好第三方框架,比如 Apache Commons File Upload, Apache MyFaces, and Oracle ADF Faces,提供了簡單的API和客戶標(biāo)簽,實(shí)現(xiàn)了這個(gè)功能。文章的前半部分將介紹上傳組件是如何工作的,在文章的后半部分,介紹了一個(gè)讓用戶通過瀏覽器上傳文件的例子。
          用JSF和MyFaces上傳文件

          作者:Andrei Cioroianu

          翻譯:RR00

          email:di_feng_ro@hotmail.com


          版權(quán)聲明:可以任意轉(zhuǎn)載,轉(zhuǎn)載時(shí)請(qǐng)務(wù)必以超鏈接形式標(biāo)明文章原始出處和作者信息及本聲明
          英文原文地址:
          http://www.onjava.com/pub/a/onjava/2005/07/13/jsfupload.html
          中文地址:
          http://www.matrix.org.cn/resource/article/43/43703_JSF_MyFaces_Upload.html
          關(guān)鍵詞: JSF MyFaces Upload



          用戶可以很方便使用瀏覽器上傳文件,但是當(dāng)前的Java Web標(biāo)準(zhǔn)(如servlets, JSP, and JSF)并沒有提供任何上傳的功能。幸好第三方框架,比如 Apache Commons File Upload, Apache MyFaces, and Oracle ADF Faces,提供了簡單的API和客戶標(biāo)簽,實(shí)現(xiàn)了這個(gè)功能。文章的前半部分將介紹上傳組件是如何工作的,你將看到MyFaces and Commons File Upload 的部分源碼(實(shí)際上,前者采用的是后者的代碼)。了解這些源碼的內(nèi)在機(jī)制將使我們更有效的使用這些框架,并且可以根據(jù)需要修改他們!在文章的后半部分,介紹了一個(gè)讓用戶通過瀏覽器上傳文件的例子。

          基于WEB的文件上傳
          “上傳”這個(gè)詞的使用比較廣泛。一個(gè)web管理員在他的主頁發(fā)布了一個(gè)文件,他可以說他上傳了一個(gè)文件;當(dāng)一個(gè)網(wǎng)絡(luò)工程師創(chuàng)建了一個(gè)HTML form和一些腳本使普通用戶可以通過瀏覽器上傳文件,他說他實(shí)現(xiàn)了上傳的功能。
          這兩種方式之中有些共同的地方,因?yàn)橐粋€(gè)web管理員可以通過一個(gè)基于web的接口來發(fā)布文件(頁面,圖像,腳本等等)。那些免費(fèi)提供個(gè)人主頁的公司,比如yahoo,實(shí)現(xiàn)了基于web的文件上傳功能,因?yàn)榭蛻粜枰蟼黜撁妗_@樣任何人只要接入網(wǎng)絡(luò),就可以通過瀏覽器發(fā)布他的個(gè)人站點(diǎn)。但是,還有許多更好的方式讓你發(fā)布你的網(wǎng)頁內(nèi)容,比如FTP或secure FTP。在這種情況下,你就需要一個(gè)對(duì)應(yīng)的應(yīng)用程序,比如FTP客戶端,而不是瀏覽器來發(fā)布你的網(wǎng)站。

          這篇文章將從網(wǎng)絡(luò)開發(fā)者的角度來討論文件上傳。一個(gè)基于web的mail應(yīng)用程序,比如yahoo mail,實(shí)現(xiàn)了上傳功能,這樣用戶才能發(fā)送信息和附件。另一個(gè)好的例子是一個(gè)job網(wǎng)站必須讓你能夠發(fā)送簡歷給招聘人員。在你的應(yīng)用程序中,你可以對(duì)上傳的文件作任何你想做的事情,比如把這些文件的內(nèi)容儲(chǔ)存到數(shù)據(jù)庫中或者把他們當(dāng)作附件發(fā)送出去。這篇文章的例子計(jì)算了上傳文件的hash值。現(xiàn)在,讓我們看看如何在一個(gè)web應(yīng)用程序中實(shí)現(xiàn)上傳功能。

          一個(gè)html表單包含一個(gè)或多個(gè)<input type="file"> 元素,這個(gè)元素將在頁面上生成文件輸入框,用戶可以在這里填寫文件路徑。用戶點(diǎn)擊輸入字段后面的瀏覽(browse)按鈕后,會(huì)彈出一個(gè)對(duì)話框讓用戶選擇路徑:

          image

          當(dāng)用戶點(diǎn)擊表單的Sumbit按鈕,瀏覽器對(duì)表單數(shù)據(jù)進(jìn)行編碼,其中包括文件的內(nèi)容,名字,路徑以及其他的表單參數(shù)。然后,瀏覽器把編碼過的數(shù)據(jù)傳遞給web服務(wù)器,服務(wù)器再把這些數(shù)據(jù)傳遞給相應(yīng)的頁面,比如<form>標(biāo)簽里的action屬性值。如果是java網(wǎng)絡(luò)應(yīng)用程序,action屬性值可能是個(gè)servlet或者是個(gè)jsp頁面。
          因?yàn)槟J(rèn)的表單編碼和get方法不適合上傳文件,所以一個(gè)包含文件輸入框的表單必須定義編碼為multipart/form-data ,并且在<form>標(biāo)簽里使用POST方法:
          <form enctype="multipart/form-data" method="POST" action="...">
          ????...
          ????<input type="file" name="...">
          ????...
          </form>


          但是,事情并不象看起來那么簡單,實(shí)現(xiàn)了servlet and JSP 標(biāo)準(zhǔn)的應(yīng)用服務(wù)器并沒有被要求處理 multipart/form-data編碼。所以你需要一個(gè)解析器來處理請(qǐng)求的輸入流,比如Apache Commons File Upload組件,它是個(gè)java包,能從已編碼的數(shù)據(jù)中讀取出上傳文件的內(nèi)容。這個(gè)包的API很靈活,允許你把小文件存在內(nèi)存里而大文件儲(chǔ)存在磁盤上一個(gè)臨時(shí)文件夾里。你不但可以定義大文件和小文件的界限,還可以定義上傳文件所占空間的最大值。

          org.apache.commons.fileupload里有個(gè)DiskFileUpload類,它的parseRequest()函數(shù)獲得一個(gè)HttpServletRequest,返回一個(gè)List,其中包含了org.apache.commons.fileupload.FileItem的實(shí)例。servlet請(qǐng)求的getInputStream()函數(shù)返回一個(gè)數(shù)據(jù)流,已編譯的表單數(shù)據(jù)就是從這里讀取出來的。FileItem很容易讓人誤解,因?yàn)檫@個(gè)接口的實(shí)例不僅包括上傳文件,還有其他的請(qǐng)求參數(shù)。

          Commons File Upload 包提供的API可以解析數(shù)據(jù),但是servlet請(qǐng)求的getParameter()函數(shù)和getParameterValues()函數(shù)卻不能工作。因?yàn)檫@兩個(gè)函數(shù)被運(yùn)行在常用的輸入框, 復(fù)選框, 單選按鈕, 和下拉列表后面的標(biāo)準(zhǔn)JSF組件調(diào)用,所以這個(gè)問題需要解決。Servlets API提供的兩個(gè)功能(filters和request wrappers) 可以解決這個(gè)問題。下面的章節(jié)描述了在沒有破壞原有JSF結(jié)構(gòu)的情況下,Apache MyFaces 如何實(shí)現(xiàn)了一個(gè)filter功能,從而添加了更多需要的支持。另外,MyFaces提供的API可以創(chuàng)建javaBean,和生成<input type="file">元素的JSF組件相對(duì)應(yīng)。

          配置 JSF 和MyFaces Extensions
          目前最主要的實(shí)現(xiàn)JSF規(guī)范的框架有JSF Reference Implementation (RI)以及Apache提供的MyFaces。雖然還有別的,但這兩個(gè)是最流行的。很多開發(fā)者更傾向于JSF RI,因?yàn)檫@是來自于sun的官方產(chǎn)品。但MyFaces有一些有趣的擴(kuò)展的功能,比如上傳文件。如果你喜歡,你可以同時(shí)使用MyFaces的擴(kuò)展功能和JSF RI。你只需要把myfaces-extensions.jar和JSF RI的jar文件以及 commons-fileupload-1.0.jar 放在web應(yīng)用程序的WEB-INF/lib 目錄下即可。下面是你需要的jar文件:

          image

          org.apache.myfaces.component.html.util包的MultipartRequestWrapper類創(chuàng)建了MyFaces和Commons File Upload連接的橋梁。這個(gè)類繼承了HttpServletRequestWrapper,重寫了getParameterMap(), getParameterNames(), getParameter(), 和getParameterValues() 函數(shù),所以他們能正確處理multipart/form-data 編碼數(shù)據(jù)。另外,MultipartRequestWrapper提供的兩個(gè)函數(shù),getFileItem() 和getFileItems(),使你可以通過org.apache.commons.fileupload.FileItem 接口訪問上傳文件。

          MyFaces的 ExtensionsFilter 類在org.apache.myfaces.component.html.util 包里,當(dāng)它發(fā)現(xiàn)multipart/form-data編碼的時(shí)候,它會(huì)創(chuàng)建 MultipartRequestWrapper 的實(shí)例。所以你不需理會(huì)他是如何解析表單數(shù)據(jù)的,但是知道它是如何開始解析對(duì)你想要修改上傳文件的處理方式是有用的。在一個(gè)傳統(tǒng)的應(yīng)用程序中,你只需要在web.xml描述符中配置好ExtensionsFilter ,它就能在JSF的FacesServlet之前截獲HTTP請(qǐng)求:

          <?xml version="1.0" encoding="UTF-8"?>
          <!DOCTYPE web-app PUBLIC
          ????"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
          ????"http://java.sun.com/dtd/web-app_2_3.dtd">
          <web-app>
          ????<context-param>
          ????????<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
          ????????<param-value>client</param-value>
          ????</context-param>
          ????<servlet>
          ????????<servlet-name>FacesServlet</servlet-name>
          ????????<servlet-class>
          ????????????javax.faces.webapp.FacesServlet
          ????????</servlet-class>
          ????????<load-on-startup>1</load-on-startup>
          ????</servlet>
          ????<servlet-mapping>
          ????????<servlet-name>FacesServlet</servlet-name>
          ????????<url-pattern>/faces/*</url-pattern>
          ????</servlet-mapping>
          ????<servlet-mapping>
          ????????<servlet-name>FacesServlet</servlet-name>
          ????????<url-pattern>*.faces</url-pattern>
          ????</servlet-mapping>
          ????<filter>
          ????????<filter-name>ExtensionsFilter</filter-name>
          ????????<filter-class>
          ????????????org.apache.myfaces.component.html.util.ExtensionsFilter
          ????????</filter-class>
          ????????<init-param>
          ????????????<param-name>uploadMaxFileSize</param-name>
          ????????????<param-value>10m</param-value>
          ????????</init-param>
          ????????<init-param>
          ????????????<param-name>uploadThresholdSize</param-name>
          ????????????<param-value>100k</param-value>
          ????????</init-param>
          ????</filter>
          ????<filter-mapping>
          ????????<filter-name>ExtensionsFilter</filter-name>
          ????????<servlet-name>FacesServlet</servlet-name>
          ????</filter-mapping>
          ????<welcome-file-list>
          ????????<welcome-file>index.jsp</welcome-file>
          ????</welcome-file-list>
          </web-app>


          前面例子中,filter的兩個(gè)參數(shù)告訴MyFaces把小于100K的文件保存在內(nèi)存中,而對(duì)于大于10M的文件則忽略。大小在uploadThresholdSize值和uploadMaxFileSize值之間的文件則作為臨時(shí)文件存在硬盤上。如果你上傳很大的文件,當(dāng)前的MyFaces版本會(huì)忽略所有的表單數(shù)據(jù),就好象你提交了一個(gè)空表單。如果你想把上傳失敗的消息告訴用戶,你就得修改MyFaces中MultipartRequestWrapper類的源碼。讓我們找到捕獲SizeLimitExceededException的地方,并使用FacesContext.getCurrentInstance().addMessage()來警告用戶。
          正如前面所說的,MyFaces Extensions 里有個(gè)能在JSF頁面里使用的上傳組件。下面的章節(jié)將說明如何使用。

          為了在web頁面里使用JSF和MyFaces,你必須使用<%@taglib%>指令聲明他們的標(biāo)簽庫。

          <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
          <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
          <%@ taglib uri="http://myfaces.apache.org/extensions" prefix="x"%>


          JSF的<h:form>標(biāo)簽沒有method屬性,因?yàn)樗恢С謕ost方法,但他有enctype屬性,當(dāng)你想上傳文件時(shí),你可以用它來定義表單數(shù)據(jù)的編碼類型:
          <f:view>
          ????<h:form id="MyForm" enctype="multipart/form-data" >
          ????????...
          ????????<x:inputFileUpload id="myFileId"
          ????????????value="#{myBean.myFile}"
          ????????????storage="file"
          ????????????required="true"/>
          ????????...
          ????</h:form>
          </f:view>


          MyFaces的<x:inputFileUpload> 標(biāo)簽讓你定義UI組件的屬性,它將在前臺(tái)生成<input type="file"> 元素。包org.apache.myfaces.custom.fileupload 包含了控制UI結(jié)構(gòu)的HtmlInputFileUpload類,它的renderer (HtmlFileUploadRenderer), 處理用戶標(biāo)簽的類 (HtmlInputFileUploadTag),??UploadedFile 接口, 以及別的幫助類。 HtmlInputFileUpload 類 繼承了標(biāo)準(zhǔn)的JSF HtmlInputText 組件 ,重寫了幾個(gè)函數(shù)。HtmlFileUploadRenderer負(fù)責(zé)創(chuàng)建 HTML 標(biāo)簽以及從MultipartRequestWrapper類返回FileItem(前面提過)。

          MyFaces提供了自己的UploadedFile接口讀取上傳文件的內(nèi)容,文件類型,名字以及大小,而不是讓你直接訪問由Commons File Upload組件創(chuàng)建的FileItem實(shí)例。你的JSF表單背后的bean必須有一個(gè)UploadedFile屬性。下面的例子中,UI組件的值通過JSF表達(dá)式(#{myBean.myFile})綁定到一個(gè)bean屬性中。JSF框架將取得HtmlInputFileUpload 組件的值,這是個(gè)UploadedFile實(shí)例,并把它傳送到背后bean的屬性中。

          import org.apache.myfaces.custom.fileupload.UploadedFile;
          ...
          public class MyBean {
          ????private UploadedFile myFile;
          ????public UploadedFile getMyFile() {
          ????????return myFile;
          ????}
          ????public void setMyFile(UploadedFile myFile) {
          ????????this.myFile = myFile;
          ????}
          ????...
          }


          我們應(yīng)該知道MyFaces有兩個(gè)實(shí)現(xiàn) UploadedFile接口的類:UploadedFileDefaultMemoryImpl和UploadedFileDefaultFileImpl。當(dāng)<x:inputFileUpload>標(biāo)簽沒有storage屬性或這個(gè)屬性值為memory時(shí),使用前一個(gè)類。當(dāng)storage屬性值為file時(shí)用后一個(gè)。

          類UploadedFileDefaultMemoryImp從一個(gè)FileItem實(shí)例中取得上傳文件的內(nèi)容以及它的名字,大小,文件類型,并把這些信息儲(chǔ)存在一個(gè)私有屬性里。所以即使Commons File Upload 把文件存在磁盤上,這個(gè)實(shí)現(xiàn)UploadedFile接口的類仍把上傳文件的內(nèi)容儲(chǔ)存在內(nèi)存里,浪費(fèi)系統(tǒng)資源。
          類UploadedFileDefaultFileImpl使用一個(gè)非序列化域(transient field)來保存一個(gè)對(duì)FileItem實(shí)例的引用。只有當(dāng)getInputStream()被調(diào)用時(shí),才通過這個(gè)引用讀取上傳文件的內(nèi)容。這個(gè)類節(jié)省了內(nèi)存空間,但如果它被序列化了,當(dāng)其被反序列化后,你無法取得文件的內(nèi)容。所以,支持上傳文件表單的bean不應(yīng)保存在session 域中,因?yàn)閼?yīng)用服務(wù)器在應(yīng)用程序重起或服務(wù)器關(guān)閉時(shí)要對(duì)session bean序列化。

          如果你想讓它們高效的工作,可以把背后的bean保存在request域并且在<x:inputFileUpload>中定義 storage="file"節(jié)省內(nèi)存資源。你可以在UploadedFileDefaultFileImpl添加一個(gè)序列化上傳文件的函數(shù)writeObject(),這樣可以解決序列化的問題。為了使這個(gè)類更有效率,相應(yīng)的readObject() 應(yīng)該創(chuàng)建臨時(shí)文件而不是從內(nèi)存中讀取它的內(nèi)容。

          應(yīng)用程序例子

          前面的章節(jié)中,我們描述了MyFaces如何使用Commons File Upload支持上傳文件功能。現(xiàn)在讓我們來看一個(gè)使用這個(gè)功能的例子。一個(gè)JSF表單(MyForm.jsp)讓用戶選擇文件以及message-digest algorithm,支持的bean(MyBean.java)計(jì)算要在別的頁面(MyResult.jsp)顯示的hash值。這些頁面以及支持的bean和一個(gè)JSF配置文件(faces-config.xml)相關(guān)聯(lián)。

          MyForm.jsp頁面
          這里的JSF表單使用MyFaces的<x:inputFileUpload>標(biāo)簽,以及一些標(biāo)準(zhǔn)JSF標(biāo)簽,這些JSF標(biāo)簽將在頁面生成labels,messages,以及一個(gè)包含message-digest algorithms的下拉列表,還有一個(gè)使用了JSF表達(dá)式的命令按鈕,這個(gè)按鈕用來定義處理上傳文件的action方法。

          <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
          <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
          <%@ taglib uri="http://myfaces.apache.org/extensions" prefix="x"%>
          <f:view>
          <h:form id="MyForm" enctype="multipart/form-data" >
          ????<h:messages globalOnly="true" styleClass="message"/>
          ????<h:panelGrid columns="3" border="0" cellspacing="5">
          ????????<h:outputLabel for="myFileId" value="File: "/>
          ????????<x:inputFileUpload id="myFileId"
          ????????????value="#{myBean.myFile}"
          ????????????storage="file"
          ????????????required="true"/>
          ????????<h:message for="myFileId"/>
          ????????<h:outputLabel for="myParamId" value="Param: "/>
          ????????<h:selectOneMenu id="myParamId"
          ????????????????value="#{myBean.myParam}"
          ????????????????required="true">
          ????????????<f:selectItem itemLabel="" itemValue=""/>
          ????????????<f:selectItem itemLabel="MD5" itemValue="MD5"/>
          ????????????<f:selectItem itemLabel="SHA-1" itemValue="SHA-1"/>
          ????????????<f:selectItem itemLabel="SHA-256" itemValue="SHA-256"/>
          ????????????<f:selectItem itemLabel="SHA-384" itemValue="SHA-384"/>
          ????????????<f:selectItem itemLabel="SHA-512" itemValue="SHA-512"/>
          ????????</h:selectOneMenu>
          ????????<h:message for="myParamId"/>
          ????????<h:outputText value=" "/>
          ????????<h:commandButton value="Submit"
          ????????????action="#{myBean.processMyFile}"/>
          ????????<h:outputText value=" "/>
          ????</h:panelGrid>
          </h:form>
          </f:view>


          processMyFile() 函數(shù)通過一個(gè)輸入流取得上傳文件的內(nèi)容,這個(gè)輸入流是通過調(diào)用myFile.getInputStream()函數(shù)返回的。hash值是使用java.security.MessageDigest計(jì)算出來的,然后這個(gè)值被轉(zhuǎn)換成一個(gè)string,用myResult屬性儲(chǔ)存。

          package com.devsphere.articles.jsfupload;
          ...
          import javax.faces.application.FacesMessage;
          import javax.faces.context.FacesContext;
          import java.security.MessageDigest;
          import java.security.NoSuchAlgorithmException;
          import java.io.*;
          public class MyBean {
          ????...
          ????public String processMyFile() {
          ????????try {
          ????????????MessageDigest md
          ????????????????= MessageDigest.getInstance(myParam);
          ????????????InputStream in = new BufferedInputStream(
          ????????????????myFile.getInputStream());
          ????????????try {
          ????????????????byte[] buffer = new byte[64 * 1024];
          ????????????????int count;
          ????????????????while ((count = in.read(buffer)) > 0)
          ????????????????????md.update(buffer, 0, count);
          ????????????} finally {
          ????????????????in.close();
          ????????????}
          ????????????byte hash[] = md.digest();
          ????????????StringBuffer buf = new StringBuffer();
          ????????????for (int i = 0; i < hash.length; i++) {
          ????????????????int b = hash[i] & 0xFF;
          ????????????????int c = (b >> 4) & 0xF;
          ????????????????c = c < 10 ? '0' + c : 'A' + c - 10;
          ????????????????buf.append((char) c);
          ????????????????c = b & 0xF;
          ????????????????c = c < 10 ? '0' + c : 'A' + c - 10;
          ????????????????buf.append((char) c);
          ????????????}
          ????????????myResult = buf.toString();
          ????????????return "OK";
          ????????} catch (Exception x) {
          ????????????FacesMessage message = new FacesMessage(
          ????????????????FacesMessage.SEVERITY_FATAL,
          ????????????????x.getClass().getName(), x.getMessage());
          ????????????FacesContext.getCurrentInstance().addMessage(
          ????????????????null, message);
          ????????????return null;
          ????????}
          ????}
          }


          faces-config.xml 文件
          這個(gè)JSF配置文件定義了支持的bean在request域以及一個(gè)導(dǎo)航規(guī)則:

          <?xml version="1.0" encoding="UTF-8"?>
          <!DOCTYPE faces-config PUBLIC
          ????"-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.1//EN"
          ????"http://java.sun.com/dtd/web-facesconfig_1_1.dtd">
          <faces-config>
          ????<managed-bean>
          ????????<managed-bean-name>myBean</managed-bean-name>
          ????????<managed-bean-class>
          ????????????com.devsphere.articles.jsfupload.MyBean
          ????????</managed-bean-class>
          ????????<managed-bean-scope>request</managed-bean-scope>
          ????</managed-bean>
          ????<navigation-rule>
          ????????<from-view-id>/MyForm.jsp</from-view-id>
          ????????<navigation-case>
          ????????????<from-outcome>OK</from-outcome>
          ????????????<to-view-id>/MyResult.jsp</to-view-id>
          ????????</navigation-case>
          ????</navigation-rule>
          </faces-config>


          MyResult.jsp 頁面
          這個(gè)web頁面顯示了關(guān)于上傳文件和hash值的一些信息:

          <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
          <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
          <f:view>
          ????<h:panelGrid columns="2" border="0" cellspacing="5">
          ????????<h:outputText value="FileName:"/>
          ????????<h:outputText value="#{myBean.myFile.name}"/>
          ????????<h:outputText value="FileSize:"/>
          ????????<h:outputText value="#{myBean.myFile.size}"/>
          ????????<h:outputText value="Param:"/>
          ????????<h:outputText value="#{myBean.myParam}"/>
          ????????<h:outputText value="Result:"/>
          ????????<h:outputText value="#{myBean.myResult}"/>
          ????</h:panelGrid>
          </f:view>


          事實(shí)上,顯示的文件名字可能是在客戶端文件系統(tǒng)的完整路徑,正如在下面的瀏覽器中看到的:

          image
          圖2. 結(jié)果圖

          總結(jié)
          在很多情況下,用戶需要通過他們的瀏覽器上傳文件,但在服務(wù)器方面并沒有處理這些文件的良好方式。把小文件保存在內(nèi)存里是可以接受的,但把大文件保存在臨時(shí)文件里會(huì)讓情況復(fù)雜。MyFaces讓你選擇的解決方法對(duì)你的應(yīng)用程序很有幫助,但這個(gè)框架有幾個(gè)小問題:當(dāng)你已不再需要某個(gè)臨時(shí)文件時(shí),它卻不讓你刪除;文件名有時(shí)候是文件路徑;并且用戶上傳過大文件時(shí)它沒有任何警告信息。但這些bug是可以修復(fù)的,因?yàn)樵创a可以修改的。這篇文章已經(jīng)說明哪些地方的代碼可以提高。不過,你可能會(huì)發(fā)現(xiàn),對(duì)于很多應(yīng)用程序來說,原有的MyFaces就已經(jīng)足夠了。這篇文章的例子是在JSF 1.1.01, MyFaces 1.0.9,和 Commons File Upload 1.0下測試的。


          資源
          本文的范例代碼:
          JavaServer Faces :http://java.sun.com/j2ee/javaserverfaces/
          Apache MyFaces (參見: CodeZoo: MyFaces) :http://myfaces.apache.org/
          Oracle ADF Faces:http://www.oracle.com/technology/products/jdev/htdocs/partners/addins/exchange/jsf/index.html
          Commons FileUpload:http://jakarta.apache.org/commons/fileupload/

          Andrei Cioroianu 是Devsphere的創(chuàng)始人,分別在ONJava, JavaWorld, 及 Java Developer's Journal??上發(fā)表了許多文章。

          Feedback

          # re: [轉(zhuǎn)]用JSF和MyFaces上傳文件  回復(fù)  更多評(píng)論   

          2007-03-16 20:51 by Derek
          你好,如果我要將文件上傳到tomcat/webapps/upload的目錄下應(yīng)該如何做?

          # re: [轉(zhuǎn)]用JSF和MyFaces上傳文件  回復(fù)  更多評(píng)論   

          2007-03-29 14:25 by itVincent
          @Derek
          把myFile寫到文件就可以了,上面的例子中沒有保存myFile

          # re: [轉(zhuǎn)]用JSF和MyFaces上傳文件[未登錄]  回復(fù)  更多評(píng)論   

          2007-05-16 15:48 by chris
          我試了下這個(gè)例子,但不知道為什么tomahawk的標(biāo)簽都顯示不出來,也不報(bào)錯(cuò),能不能告訴我你的QQ或者M(jìn)SN,我們交流一下

          # re: [轉(zhuǎn)]用JSF和MyFaces上傳文件  回復(fù)  更多評(píng)論   

          2007-05-18 16:37 by itVincent
          可以發(fā)我郵件itvincent@126.com,大家交流一下
          主站蜘蛛池模板: 怀化市| 乌拉特后旗| 卢湾区| 长沙县| 河间市| 临城县| 沙田区| 民县| 沅陵县| 盐边县| 德保县| 眉山市| 石阡县| 咸丰县| 乐平市| 枝江市| 瓦房店市| 高尔夫| 贵州省| 绍兴市| 米泉市| 安岳县| 阜阳市| 甘南县| 洱源县| 泸溪县| 西藏| 寿宁县| 水富县| 敦化市| 宁远县| 托克托县| 华宁县| 新绛县| 壤塘县| 张家界市| 城固县| 营山县| 普定县| 广安市| 鹰潭市|