﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-VIRGIN FOREST OF JAVA-文章分类-JSF</title><link>http://www.blogjava.net/RR00/category/2949.html</link><description>不要埋头苦干，要学习，学习，再学习。。。。。
&lt;br&gt;
powered  by &lt;font color='orange'&gt;R.Zeus&lt;/font&gt;</description><language>zh-cn</language><lastBuildDate>Sat, 19 Jan 2008 00:53:50 GMT</lastBuildDate><pubDate>Sat, 19 Jan 2008 00:53:50 GMT</pubDate><ttl>60</ttl><item><title>rich faces in jsf page</title><link>http://www.blogjava.net/RR00/articles/176264.html</link><dc:creator>R.Zeus</dc:creator><author>R.Zeus</author><pubDate>Fri, 18 Jan 2008 08:12:00 GMT</pubDate><guid>http://www.blogjava.net/RR00/articles/176264.html</guid><wfw:comment>http://www.blogjava.net/RR00/comments/176264.html</wfw:comment><comments>http://www.blogjava.net/RR00/articles/176264.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/RR00/comments/commentRss/176264.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/RR00/services/trackbacks/176264.html</trackback:ping><description><![CDATA[if the jsf page contains validate component, the ajax will call the validate method, if failed, the action will failed.<br />
actually, the ajax is the same as the form submit, so it will&nbsp; validate the form. <br />
if they are in different form, may be this will solved.<br />
<img src ="http://www.blogjava.net/RR00/aggbug/176264.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/RR00/" target="_blank">R.Zeus</a> 2008-01-18 16:12 <a href="http://www.blogjava.net/RR00/articles/176264.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>通过JSF和MYFaces上传文件</title><link>http://www.blogjava.net/RR00/articles/10956.html</link><dc:creator>R.Zeus</dc:creator><author>R.Zeus</author><pubDate>Wed, 24 Aug 2005 14:32:00 GMT</pubDate><guid>http://www.blogjava.net/RR00/articles/10956.html</guid><wfw:comment>http://www.blogjava.net/RR00/comments/10956.html</wfw:comment><comments>http://www.blogjava.net/RR00/articles/10956.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/RR00/comments/commentRss/10956.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/RR00/services/trackbacks/10956.html</trackback:ping><description><![CDATA[<P>原文：<A href="http://www.onjava.com/pub/a/onjava/2005/07/13/jsfupload.html">http://www.onjava.com/pub/a/onjava/2005/07/13/jsfupload.html</A><BR>作者：<A href="http://www.onjava.com/pub/au/1218">Andrei Cioroianu</A><BR>翻译：<A href="mailto:di_feng_ro@hotmail.com"><FONT color=#1d58d1>di_feng_ro@hotmail.com</FONT></A><BR><BR>用户可以很方便使用浏览器上传文件，但是当前的Java Web标准（如servlets, JSP, and JSF）并没有提供任何上传的功能。幸好第三方框架，比如 Apache Commons File Upload, Apache MyFaces, and Oracle ADF Faces，提供了简单的API和客户标签，实现了这个功能。文章的前半部分将介绍上传组件是如何工作的，你将看到MyFaces and Commons File Upload 的部分源码（实际上，前者采用的是后者的代码）。了解这些源码的内在机制将使我们更有效的使用这些框架，并且可以根据需要修改他们！在文章的后半部分，介绍了一个让用户通过浏览器上传文件的例子。<BR><BR><STRONG>基于WEB的文件上传</STRONG></P>
<P>“上传”这个词的使用比较广泛。一个web管理员在他的主页发布了一个文件，他可以说他上传了一个文件；当一个网络工程师创建了一个HTML form和一些脚本使普通用户可以通过浏览器上传文件，他说他实现了上传的功能。</P>
<P>这两种方式之中有些共同的地方，因为一个web管理员可以通过一个基于web的接口来发布文件（页面，图像，脚本等等）。那些免费提供个人主页的公司，比如yahoo，实现了基于web的文件上传功能，因为客户需要上传页面。这样任何人只要接入网络，就可以通过浏览器发布他的个人站点。但是，还有许多更好的方式让你发布你的网页内容，比如FTP或secure FTP。在这种情况下，你就需要一个对应的应用程序，比如FTP客户端，而不是浏览器来发布你的网站。<BR><BR><BR>这篇文章将从网络开发者的角度来讨论文件上传。一个基于web的mail应用程序，比如yahoo mail,实现了上传功能，这样用户才能发送信息和附件。另一个好的例子是一个job网站必须让你能够发送简历给招聘人员。在你的应用程序中，你可以对上传的文件作任何你想做的事情，比如把这些文件的内容储存到数据库中或者把他们当作附件发送出去。这篇文章的例子计算了上传文件的hash值。现在，让我们看看如何在一个web应用程序中是实现上传功能。<BR><BR><BR>一个html表单包含一个或多个&lt;input type="file"&gt; 元素，这个元素将在页面上生成文件输入框，用户可以在这里填写文件路径。用户点击输入字段后面的浏览(browse)按钮后，会弹出一个对话框让用户选择路径：<BR><IMG height=304 alt="Web form containing a file input field" src="http://www.onjava.com/onjava/2005/07/13/graphics/MyForm.gif" width=426></P>
<P>当用户点击表单的Sumbit按钮，浏览器对表单数据进行编码，其中包括文件的内容，名字，路径以及其他的表单参数。然后，浏览器把编码过的数据传递给web服务器，服务器再把这些数据传递给相应的页面，比如&lt;form&gt;标签里的action属性值。如果是java网络应用程序，action属性值可能是个servlet或者是个jsp页面。</P>
<P>因为默认的表单编码和get方法不适合上传文件，所以一个包含文件输入框的表单必须定义编码为multipart/form-data ，并且在&lt;form&gt;标签里使用POST方法：</P>
<P><FONT style="BACKGROUND-COLOR: #f5f5dc">&lt;form enctype="multipart/form-data" method="POST" action="..."&gt;<BR>&nbsp;&nbsp;&nbsp; ...<BR>&nbsp;&nbsp;&nbsp; &lt;input type="file" name="..."&gt;<BR>&nbsp;&nbsp;&nbsp; ...<BR>&lt;/form&gt;</FONT></P>
<P>但是，事情并不象看起来那么简单，实现了servlet and JSP 标准的应用服务器并没有被要求处理 multipart/form-data编码。所以你需要一个解析器来处理请求的输入流,比如Apache Commons File Upload组件，它是个java包，能从已编码的数据中读取出上传文件的内容。这个包的API很灵活，允许你把小文件存在内存里而大文件储存在磁盘上一个临时文件夹里。你不但可以定义大文件和小文件的界限，还可以定义上传文件所占空间的最大值。</P>
<P><BR>org.apache.commons.fileupload里有个DiskFileUpload类，它的parseRequest()函数获得一个HttpServletRequest，返回一个List，其中包含了org.apache.commons.fileupload.FileItem的实例。servlet请求的getInputStream()函数返回一个数据流，已编译的表单数据就是从这里读取出来的。FileItem很容易让人误解，因为这个接口的实例不仅包括上传文件,还有其他的请求参数。</P>
<P>Commons File Upload 包提供的API可以解析数据，但是servlet请求的getParameter()函数和getParameterValues()函数却不能工作。因为这两个函数被运行在常用的输入框, 复选框, 单选按钮, 和下拉列表后面的标准JSF组件调用，所以这个问题需要解决。Servlets API提供的两个功能(filters和request wrappers) 可以解决这个问题。下面的章节描述了在没有破坏原有JSF结构的情况下，Apache MyFaces 如何实现了一个filter功能，从而添加了更多需要的支持。另外，MyFaces提供的API可以创建javaBean，和生成&lt;input type="file"&gt;元素的JSF组件相对应。</P>
<P><BR><STRONG>配置&nbsp;JSF 和MyFaces Extensions</STRONG></P>
<P>目前最主要的实现JSF规范的框架有JSF Reference Implementation (RI)以及Apache提供的MyFaces。虽然还有别的，但这两个是最流行的。很多开发者更倾向于JSF RI，因为这是来自于sun的官方产品。但MyFaces有一些有趣的扩展的功能，比如上传文件。如果你喜欢，你可以同时使用MyFaces的扩展功能和JSF RI。你只需要把myfaces-extensions.jar和JSF RI的jar文件以及 commons-fileupload-1.0.jar 放在web应用程序的WEB-INF/lib 目录下即可。下面是你需要的jar文件：<BR>
<TABLE cellPadding=5 summary="Needed JARs" border=1>
<TBODY>
<TR>
<TD>JSF 1.1 RI</TD>
<TD><EM>jsf-api.jar</EM><BR><EM>jsf-impl.jar</EM></TD></TR>
<TR>
<TD>JSTL 1.1 RI</TD>
<TD><EM>jstl.jar</EM><BR><EM>standard.jar</EM></TD></TR>
<TR>
<TD>MyFaces Extensions</TD>
<TD><EM>myfaces-extensions.jar</EM></TD></TR>
<TR>
<TD>Apache Commons<BR>(used by JSF and<BR>MyFaces Extensions)</TD>
<TD><EM>commons-collections.jar</EM><BR><EM>commons-digester.jar</EM><BR><EM>commons-beanutils.jar</EM><BR><EM>commons-logging.jar</EM><BR><EM>commons-fileupload-1.0.jar</EM></TD></TR></TBODY></TABLE></P>
<P>org.apache.myfaces.component.html.util包的MultipartRequestWrapper类创建了MyFaces和Commons File Upload连接的桥梁。这个类继承了HttpServletRequestWrapper，重写了getParameterMap(), getParameterNames(), getParameter(), 和getParameterValues() 函数，所以他们能正确处理multipart/form-data 编码数据。另外，MultipartRequestWrapper提供的两个函数，getFileItem() 和getFileItems(),使你可以通过org.apache.commons.fileupload.FileItem 接口访问上传文件。</P>
<P><BR>MyFaces的 ExtensionsFilter 类在org.apache.myfaces.component.html.util 包里，当它发现multipart/form-data编码的时候，它会创建了 MultipartRequestWrapper 的实例。所以你不需理会他是如何解析表单数据的，但是知道它是如何开始解析对你想要修改上传文件的处理方式是有用的。在一个传统的应用程序中，你只需要在web.xml描述符中配置好ExtensionsFilter ，它就能在JSF的FacesServlet之前截获HTTP请求：</P>
<P><FONT style="BACKGROUND-COLOR: #f5f5dc">&lt;?xml version="1.0" encoding="UTF-8"?&gt;</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #f5f5dc">&lt;!DOCTYPE web-app PUBLIC<BR>&nbsp;&nbsp;&nbsp; "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"<BR>&nbsp;&nbsp;&nbsp; "</FONT><A href="http://java.sun.com/dtd/web-app_2_3.dtd"><FONT style="BACKGROUND-COLOR: #f5f5dc">http://java.sun.com/dtd/web-app_2_3.dtd</FONT></A><FONT style="BACKGROUND-COLOR: #f5f5dc">"&gt;</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #f5f5dc">&lt;web-app&gt;</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #f5f5dc">&nbsp;&nbsp;&nbsp; &lt;context-param&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;param-name&gt;javax.faces.STATE_SAVING_METHOD&lt;/param-name&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;param-value&gt;client&lt;/param-value&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;/context-param&gt;</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #f5f5dc">&nbsp;&nbsp;&nbsp; &lt;servlet&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;servlet-name&gt;FacesServlet&lt;/servlet-name&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;servlet-class&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; javax.faces.webapp.FacesServlet<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/servlet-class&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;load-on-startup&gt;1&lt;/load-on-startup&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;/servlet&gt;</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #f5f5dc">&nbsp;&nbsp;&nbsp; &lt;servlet-mapping&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;servlet-name&gt;FacesServlet&lt;/servlet-name&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;url-pattern&gt;/faces/*&lt;/url-pattern&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;/servlet-mapping&gt;</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #f5f5dc">&nbsp;&nbsp;&nbsp; &lt;servlet-mapping&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;servlet-name&gt;FacesServlet&lt;/servlet-name&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;url-pattern&gt;*.faces&lt;/url-pattern&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;/servlet-mapping&gt;</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #f5f5dc">&nbsp;&nbsp;&nbsp; &lt;filter&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;filter-name&gt;ExtensionsFilter&lt;/filter-name&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;filter-class&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; org.apache.myfaces.component.html.util.ExtensionsFilter<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/filter-class&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;init-param&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;param-name&gt;uploadMaxFileSize&lt;/param-name&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;param-value&gt;10m&lt;/param-value&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/init-param&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;init-param&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;param-name&gt;uploadThresholdSize&lt;/param-name&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;param-value&gt;100k&lt;/param-value&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/init-param&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;/filter&gt;</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #f5f5dc">&nbsp;&nbsp;&nbsp; &lt;filter-mapping&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;filter-name&gt;ExtensionsFilter&lt;/filter-name&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;servlet-name&gt;FacesServlet&lt;/servlet-name&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;/filter-mapping&gt;</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #f5f5dc">&nbsp;&nbsp;&nbsp; &lt;welcome-file-list&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;welcome-file&gt;index.jsp&lt;/welcome-file&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;/welcome-file-list&gt;</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #f5f5dc">&lt;/web-app&gt;</FONT></P>
<P><BR>&nbsp;前面例子中，filter的两个参数告诉MyFaces把小于100K的文件保存在内存中，而对于大于10M的文件则忽略。大小在<FONT style="BACKGROUND-COLOR: #f5f5dc">uploadThresholdSize</FONT>值和<FONT style="BACKGROUND-COLOR: #f5f5dc">uploadMaxFileSize</FONT>值之间的文件则作为临时文件存在硬盘上。如果你上传很大的文件，当前的MyFaces版本会忽略所有的表单数据，就好象你提交了一个空表单。如果你想把上传失败的消息告诉用户，你就得修改MyFaces中MultipartRequestWrapper类的源码。让我们找到捕获SizeLimitExceededException的地方，并使用FacesContext.getCurrentInstance().addMessage()来警告用户。</P>
<P>正如前面所说的，MyFaces Extensions 里有个能在JSF页面里使用的上传组件。下面的章节将说明如何使用。</P>
<P>为了在web页面里使用JSF和MyFaces，你必须使用&lt;<A href="mailto:%@taglib%">%@taglib%</A>&gt;指令声明他们的标签库。</P>
<P><FONT style="BACKGROUND-COLOR: #f5f5dc">&lt;%@ taglib uri="</FONT><A href="http://java.sun.com/jsf/core"><FONT style="BACKGROUND-COLOR: #f5f5dc">http://java.sun.com/jsf/core</FONT></A><FONT style="BACKGROUND-COLOR: #f5f5dc">" prefix="f"%&gt;<BR>&lt;%@ taglib uri="</FONT><A href="http://java.sun.com/jsf/html"><FONT style="BACKGROUND-COLOR: #f5f5dc">http://java.sun.com/jsf/html</FONT></A><FONT style="BACKGROUND-COLOR: #f5f5dc">" prefix="h"%&gt;<BR>&lt;%@ taglib uri="</FONT><A href="http://myfaces.apache.org/extensions"><FONT style="BACKGROUND-COLOR: #f5f5dc">http://myfaces.apache.org/extensions</FONT></A><FONT style="BACKGROUND-COLOR: #f5f5dc">" prefix="x"%&gt;</FONT></P>
<P><BR>JSF的&lt;h:form&gt;标签没有method属性，因为它只支持post方法，但他有enctype属性，当你想上传文件时，你可以用它来定义表单数据的编码类型：</P>
<P><FONT style="BACKGROUND-COLOR: #f5f5dc">&lt;f:view&gt;</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #f5f5dc">&nbsp;&nbsp;&nbsp; &lt;h:form id="MyForm" enctype="multipart/form-data" &gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ...<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;x:inputFileUpload id="myFileId"<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; value="#{myBean.myFile}"<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; storage="file"<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; required="true"/&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ...<BR>&nbsp;&nbsp;&nbsp; &lt;/h:form&gt;</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #f5f5dc">&lt;/f:view&gt;</FONT></P>
<P>&nbsp;</P>
<P>MyFaces的&lt;x:inputFileUpload&gt; 标签让你定义UI组件的属性，它将在前台生成&lt;input type="file"&gt; 元素。包org.apache.myfaces.custom.fileupload 包含了控制UI结构的HtmlInputFileUpload类，它的renderer (HtmlFileUploadRenderer), 处理用户标签的类 (HtmlInputFileUploadTag),&nbsp; UploadedFile 接口, 以及别的帮助类。 HtmlInputFileUpload 类 继承了标准的JSF HtmlInputText 组件 ，重写了几个函数。HtmlFileUploadRenderer负责创建 HTML 标签以及从MultipartRequestWrapper类返回FileItem(前面提过)。</P>
<P>MyFaces提供了自己的UploadedFile接口读取上传文件的内容，文件类型，名字以及大小，而不是让你直接访问由Commons File Upload组件创建的FileItem实例。你的JSF表单背后的bean必须有一个UploadedFile属性。下面的例子中，UI组件的值通过JSF表达式(#{myBean.myFile})绑定到一个bean属性中。JSF框架将取得HtmlInputFileUpload 组件的值，这是个UploadedFile实例，并把它传送到背后bean的属性中。</P>
<P><FONT style="BACKGROUND-COLOR: #f5f5dc">import org.apache.myfaces.custom.fileupload.UploadedFile;<BR>...<BR>public class MyBean {<BR>&nbsp;&nbsp;&nbsp; private UploadedFile myFile;</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #f5f5dc">&nbsp;&nbsp;&nbsp; public UploadedFile getMyFile() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return myFile;<BR>&nbsp;&nbsp;&nbsp; }</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #f5f5dc">&nbsp;&nbsp;&nbsp; public void setMyFile(UploadedFile myFile) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.myFile = myFile;<BR>&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; ...<BR>}</FONT></P>
<P>我们应该知道MyFaces有两个实现 UploadedFile接口的类:<FONT style="BACKGROUND-COLOR: #deb887">UploadedFileDefaultMemoryImpl</FONT>和<FONT style="BACKGROUND-COLOR: #deb887">UploadedFileDefaultFileImpl</FONT>。当&lt;x:inputFileUpload&gt;标签没有storage属性或这个属性值为memory时，使用前一个类。当storage属性值为file时用后一个。</P>
<P>类UploadedFileDefaultMemoryImp从一个FileItem实例中取得上传文件的内容以及它的名字，大小，文件类型，并把这些信息储存在一个私有属性里。所以即使Commons File Upload 把文件存在磁盘上，这个实现UploadedFile接口的类仍把上传文件的内容储存在内存里，浪费系统资源。</P>
<P>类UploadedFileDefaultFileImpl使用一个临时属性来保存一个对FileItem实例的引用。只有当getInputStream()被调用时，才通过这个引用读取上传文件的内容。这个类节省了内存空间，但它是序列化的，当其被反序列化后，你无法取得文件的内容。所以，上传文件表单背后的bean无法保存在session scope中，因为应用服务器在应用程序重起或服务器关闭时要对session bean序列化。(译者注：这一段不太明白，希望大家给予指导）。</P>
<P>如果你想让它们高效的工作，可以把背后的bean保存在request scope并且在&lt;x:inputFileUpload&gt;中定义 storage="file"节省内存资源。你可以在UploadedFileDefaultFileImpl添加一个序列化上传文件的函数writeObject()，这样可以解决序列化的问题。为了使这个类更有效率，相应的readObject() 应该创建临时文件而不是从内存中读取它的内容。</P>
<P><STRONG>&nbsp;应用程序例子</STRONG></P>
<P><BR>前面的章节中，我们描述了MyFaces如何使用Commons File Upload支持上传文件功能。现在让我们来看一个使用这个功能的例子。一个JSF表单(MyForm.jsp）让用户选择文件以及message-digest algorithm，背后的bean(MyBean.java)计算要在别的页面(MyResult.jsp)显示的hash值。这些页面以及背后的bean和一个JSF配置文件(faces-config.xml)相关联。</P>
<P>MyForm.jsp页面</P>
<P>这里的JSF表单使用MyFaces的&lt;x:inputFileUpload&gt;标签，以及一些标准JSF标签,这些JSF标签将在页面生成labels,messages,以及一个包含message-digest algorithms的下拉列表，还有一个使用了JSF表达式的命令按钮，这个按钮用来定义处理上传文件的action方法。<BR><BR><FONT style="BACKGROUND-COLOR: #f5f5dc">&lt;%@ taglib uri="</FONT><A href="http://java.sun.com/jsf/core"><FONT style="BACKGROUND-COLOR: #f5f5dc">http://java.sun.com/jsf/core</FONT></A><FONT style="BACKGROUND-COLOR: #f5f5dc">" prefix="f"%&gt;<BR>&lt;%@ taglib uri="</FONT><A href="http://java.sun.com/jsf/html"><FONT style="BACKGROUND-COLOR: #f5f5dc">http://java.sun.com/jsf/html</FONT></A><FONT style="BACKGROUND-COLOR: #f5f5dc">" prefix="h"%&gt;<BR>&lt;%@ taglib uri="</FONT><A href="http://myfaces.apache.org/extensions"><FONT style="BACKGROUND-COLOR: #f5f5dc">http://myfaces.apache.org/extensions</FONT></A><FONT style="BACKGROUND-COLOR: #f5f5dc">" prefix="x"%&gt;</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #f5f5dc">&lt;f:view&gt;</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #f5f5dc">&lt;h:form id="MyForm" enctype="multipart/form-data" &gt;</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #f5f5dc">&nbsp;&nbsp;&nbsp; &lt;h:messages globalOnly="true" styleClass="message"/&gt;</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #f5f5dc">&nbsp;&nbsp;&nbsp; &lt;h:panelGrid columns="3" border="0" cellspacing="5"&gt;</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #f5f5dc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;h:outputLabel for="myFileId" value="File: "/&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;x:inputFileUpload id="myFileId"<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; value="#{myBean.myFile}"<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; storage="file"<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; required="true"/&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;h:message for="myFileId"/&gt;</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #f5f5dc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;h:outputLabel for="myParamId" value="Param: "/&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;h:selectOneMenu id="myParamId"<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; value="#{myBean.myParam}"<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; required="true"&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;f:selectItem itemLabel="" itemValue=""/&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;f:selectItem itemLabel="MD5" itemValue="MD5"/&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;f:selectItem itemLabel="SHA-1" itemValue="SHA-1"/&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;f:selectItem itemLabel="SHA-256" itemValue="SHA-256"/&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;f:selectItem itemLabel="SHA-384" itemValue="SHA-384"/&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;f:selectItem itemLabel="SHA-512" itemValue="SHA-512"/&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/h:selectOneMenu&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;h:message for="myParamId"/&gt;</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #f5f5dc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;h:outputText value=" "/&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;h:commandButton value="Submit"<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; action="#{myBean.processMyFile}"/&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;h:outputText value=" "/&gt;</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #f5f5dc">&nbsp;&nbsp;&nbsp; &lt;/h:panelGrid&gt;</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #f5f5dc">&lt;/h:form&gt;</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #f5f5dc">&lt;/f:view&gt;<BR></FONT></P>
<P>processMyFile() 函数通过一个输入流取得上传文件的内容，这个输入流是通过调用myFile.getInputStream()函数返回的。hash值是使用java.security.MessageDigest计算出来的，然后这个值被转换成一个string,用myResult属性储存。<BR><FONT style="BACKGROUND-COLOR: #f5f5dc">package com.devsphere.articles.jsfupload;<BR>...<BR>import javax.faces.application.FacesMessage;<BR>import javax.faces.context.FacesContext;</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #f5f5dc">import java.security.MessageDigest;<BR>import java.security.NoSuchAlgorithmException;</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #f5f5dc">import java.io.*;</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #f5f5dc">public class MyBean {<BR>&nbsp;&nbsp;&nbsp; ...<BR>&nbsp;&nbsp;&nbsp; public String processMyFile() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MessageDigest md<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = MessageDigest.getInstance(myParam);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; InputStream in = new BufferedInputStream(<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; myFile.getInputStream());<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; byte[] buffer = new byte[64 * 1024];<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int count;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while ((count = in.read(buffer)) &gt; 0)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; md.update(buffer, 0, count);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } finally {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; in.close();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; byte hash[] = md.digest();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; StringBuffer buf = new StringBuffer();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int i = 0; i &lt; hash.length; i++) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int b = hash[i] &amp; 0xFF;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int c = (b &gt;&gt; 4) &amp; 0xF;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; c = c &lt; 10 ? '0' + c : 'A' + c - 10;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; buf.append((char) c);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; c = b &amp; 0xF;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; c = c &lt; 10 ? '0' + c : 'A' + c - 10;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; buf.append((char) c);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; myResult = buf.toString();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return "OK";<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch (Exception x) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FacesMessage message = new FacesMessage(<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FacesMessage.SEVERITY_FATAL,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; x.getClass().getName(), x.getMessage());<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FacesContext.getCurrentInstance().addMessage(<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; null, message);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return null;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; }</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #f5f5dc">}</FONT></P>
<P>&nbsp;</P>
<P><STRONG>faces-config.xml 文件</STRONG></P>
<P>这个JSF配置文件定义了背后的bean在request scope以及一个导航规则：</P>
<P><FONT style="BACKGROUND-COLOR: #f5f5dc">&lt;?xml version="1.0" encoding="UTF-8"?&gt;</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #f5f5dc">&lt;!DOCTYPE faces-config PUBLIC<BR>&nbsp;&nbsp;&nbsp; "-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.1//EN"<BR>&nbsp;&nbsp;&nbsp; "</FONT><A href="http://java.sun.com/dtd/web-facesconfig_1_1.dtd"><FONT style="BACKGROUND-COLOR: #f5f5dc">http://java.sun.com/dtd/web-facesconfig_1_1.dtd</FONT></A><FONT style="BACKGROUND-COLOR: #f5f5dc">"&gt;</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #f5f5dc">&lt;faces-config&gt;</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #f5f5dc">&nbsp;&nbsp;&nbsp; &lt;managed-bean&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;managed-bean-name&gt;myBean&lt;/managed-bean-name&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;managed-bean-class&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; com.devsphere.articles.jsfupload.MyBean<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/managed-bean-class&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;managed-bean-scope&gt;request&lt;/managed-bean-scope&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;/managed-bean&gt;</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #f5f5dc">&nbsp;&nbsp;&nbsp; &lt;navigation-rule&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;from-view-id&gt;/MyForm.jsp&lt;/from-view-id&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;navigation-case&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;from-outcome&gt;OK&lt;/from-outcome&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;to-view-id&gt;/MyResult.jsp&lt;/to-view-id&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/navigation-case&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;/navigation-rule&gt;</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #f5f5dc">&lt;/faces-config&gt;</FONT></P>
<P>&nbsp;<STRONG>MyResult.jsp 页面</STRONG></P>
<P>这个web页面显示了关于上传文件和hash值的一些信息：</P>
<P><FONT style="BACKGROUND-COLOR: #f5f5dc">&lt;%@ taglib uri="</FONT><A href="http://java.sun.com/jsf/core"><FONT style="BACKGROUND-COLOR: #f5f5dc">http://java.sun.com/jsf/core</FONT></A><FONT style="BACKGROUND-COLOR: #f5f5dc">" prefix="f"%&gt;<BR>&lt;%@ taglib uri="</FONT><A href="http://java.sun.com/jsf/html"><FONT style="BACKGROUND-COLOR: #f5f5dc">http://java.sun.com/jsf/html</FONT></A><FONT style="BACKGROUND-COLOR: #f5f5dc">" prefix="h"%&gt;</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #f5f5dc">&lt;f:view&gt;</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #f5f5dc">&nbsp;&nbsp;&nbsp; &lt;h:panelGrid columns="2" border="0" cellspacing="5"&gt;</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #f5f5dc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;h:outputText value="FileName:"/&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;h:outputText value="#{myBean.myFile.name}"/&gt;</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #f5f5dc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;h:outputText value="FileSize:"/&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;h:outputText value="#{myBean.myFile.size}"/&gt;</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #f5f5dc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;h:outputText value="Param:"/&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;h:outputText value="#{myBean.myParam}"/&gt;</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #f5f5dc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;h:outputText value="Result:"/&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;h:outputText value="#{myBean.myResult}"/&gt;</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #f5f5dc">&nbsp;&nbsp;&nbsp; &lt;/h:panelGrid&gt;</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #f5f5dc">&lt;/f:view&gt;</FONT></P>
<P><BR>事实上，显示的文件名字可能是在客户端文件系统的完整路径，正如在下面的浏览器中看到的：</P>
<P><STRONG>总结<BR></STRONG></P>
<P>在很多情况下，用户需要通过他们的浏览器上传文件，但在服务器方面并没有处理这些文件的良好方式。把小文件保存在内存里是可以接受的，但把大文件保存在临时文件里会让情况复杂。MyFaces让你选择的解决方法对你的应用程序很有帮助，但这个框架有几个小问题：当你已不再需要某个临时文件时，它却不让你删除；文件名有时候是文件路径；并且用户上传过大文件时它没有任何警告信息。但这些bug是可以修复的，因为源码可以修改的。这篇文章已经说明哪些地方的代码可以提高。不过，你可能会发现，对于很多应用程序来说，原有的MyFaces就已经足够了。这篇文章的例子是在JSF 1.1.01, MyFaces 1.0.9,和 Commons File Upload 1.0下测试的。</P>
<P>&nbsp;</P>
<P>&nbsp;</P>
<P><BR>&nbsp;</P><img src ="http://www.blogjava.net/RR00/aggbug/10956.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/RR00/" target="_blank">R.Zeus</a> 2005-08-24 22:32 <a href="http://www.blogjava.net/RR00/articles/10956.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JSF Expression Language </title><link>http://www.blogjava.net/RR00/articles/10736.html</link><dc:creator>R.Zeus</dc:creator><author>R.Zeus</author><pubDate>Mon, 22 Aug 2005 13:32:00 GMT</pubDate><guid>http://www.blogjava.net/RR00/articles/10736.html</guid><wfw:comment>http://www.blogjava.net/RR00/comments/10736.html</wfw:comment><comments>http://www.blogjava.net/RR00/articles/10736.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/RR00/comments/commentRss/10736.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/RR00/services/trackbacks/10736.html</trackback:ping><description><![CDATA[转自：<A href="http://www.javaworld.com.tw/confluence/pages/viewpage.action?pageId=2630">http://www.javaworld.com.tw/confluence/pages/viewpage.action?pageId=2630</A><BR><BR>JSF Expression Language 搭配 JSF 標籤來使用，是用來存取資料物件的一個簡易語言。 
<P>　　JSF EL是以#開始，將變數或運算式放置在 
<DIV class=error><SPAN class=error>Unknown macro: { 與 }</SPAN> </DIV>之間，例如： 
<P></P>
<DIV class=code style="BORDER-TOP-STYLE: solid; BORDER-RIGHT-STYLE: solid; BORDER-LEFT-STYLE: solid; BORDER-BOTTOM-STYLE: solid">
<DIV class=codeContent><PRE class=code-java>#{someBeanName}</PRE></DIV></DIV>
<P>　　變數名稱可以是faces-config.xml中定義的名稱，如果是Bean的話，可以透過使用 '.' 運算子來存取它的屬性，例如：</P>
<DIV class=code style="BORDER-TOP-STYLE: solid; BORDER-RIGHT-STYLE: solid; BORDER-LEFT-STYLE: solid; BORDER-BOTTOM-STYLE: solid">
<DIV class=codeContent><PRE class=code-java>...
 &lt;f:view&gt;
    &lt;h:outputText value=<SPAN class=code-quote>"#{userBean.name}"</SPAN>/&gt;
 &lt;/f:view&gt;
 ...</PRE></DIV></DIV>
<P>　　在JSF標籤的屬性上，" 與 " （或'與'）之間如果含有EL，則會加以運算，您也可以這麼使用它：</P>
<DIV class=code style="BORDER-TOP-STYLE: solid; BORDER-RIGHT-STYLE: solid; BORDER-LEFT-STYLE: solid; BORDER-BOTTOM-STYLE: solid">
<DIV class=codeContent><PRE class=code-java>...
 &lt;f:view&gt;
    名稱, 年齡：&lt;h:outputText 
                  value=<SPAN class=code-quote>"#{userBean.name}, #{userBean.age}"</SPAN>/&gt;
 &lt;/f:view&gt;
 ...</PRE></DIV></DIV>
<P>　　一個執行的結果可能是這樣顯示的：</P>
<DIV class=code style="BORDER-TOP-STYLE: solid; BORDER-RIGHT-STYLE: solid; BORDER-LEFT-STYLE: solid; BORDER-BOTTOM-STYLE: solid">
<DIV class=codeContent><PRE class=code-java>名稱, 年齡：Justin, 29</PRE></DIV></DIV>
<P>　　EL的變數名也可以程式執行過程中所宣告的名稱，或是JSF EL預設的隱含物件，例如下面的程式使用param隱含物件來取得使用者輸入的參數：</P>
<DIV class=code style="BORDER-TOP-STYLE: solid; BORDER-RIGHT-STYLE: solid; BORDER-LEFT-STYLE: solid; BORDER-BOTTOM-STYLE: solid">
<DIV class=codeContent><PRE class=code-java>&lt;%@ taglib uri=<SPAN class=code-quote>"http:<SPAN class=code-comment>//java.sun.com/jsf/core"</SPAN> prefix=<SPAN class=code-quote>"f"</SPAN> %&gt;
</SPAN> &lt;%@ taglib uri=<SPAN class=code-quote>"http:<SPAN class=code-comment>//java.sun.com/jsf/html"</SPAN> prefix=<SPAN class=code-quote>"h"</SPAN> %&gt;
</SPAN> &lt;%@page contentType=<SPAN class=code-quote>"text/html; charset=Big5"</SPAN>%&gt;
      
 &lt;html&gt;
 &lt;head&gt;
 &lt;title&gt;&lt;/title&gt;
 &lt;/head&gt;
 &lt;body&gt;
 &lt;f:view&gt;
    &lt;b&gt; 您好, &lt;h:outputText value=<SPAN class=code-quote>"#{param.name}"</SPAN>/&gt; &lt;/b&gt;
 &lt;/f:view&gt;

 &lt;/body&gt;
 &lt;/html&gt;</PRE></DIV></DIV>
<P>　　param是JSF EL預設的隱含物件變數，它代表request所有參數的集合，實際是一個java.util.Map型態物件，JSF所提供的隱含物件，大致上對應於<SPAN class=nobr><A title="Visit page outside Confluence" href="http://www.javaworld.com.tw/confluence/pages/viewpage.action?pageId=1036" rel=nofollow>JSP隱含物件<SUP><IMG class=rendericon height=7 alt="" src="http://www.javaworld.com.tw/confluence/images/icons/linkext7.gif" width=7 align=absMiddle border=0></SUP></A></SPAN>，不過JSF隱含物件移除了pageScope與pageContext，而增加了facesContext與view，它們分別對應於 javax.faces.context.FacesContext與javax.faces.component.UIViewRoot。</P>
<P>　　對於Map型態物件，我們可以使用 '.' 運算子指定key值來取出對應的value，也可以使用 [ 與 ] 來指定，例如：</P>
<DIV class=code style="BORDER-TOP-STYLE: solid; BORDER-RIGHT-STYLE: solid; BORDER-LEFT-STYLE: solid; BORDER-BOTTOM-STYLE: solid">
<DIV class=codeContent><PRE class=code-java>...
 &lt;f:view&gt;
    &lt;b&gt; 您好, &lt;h:outputText value=<SPAN class=code-quote>"#{param['name']}"</SPAN>/&gt; &lt;/b&gt;
 &lt;/f:view&gt;
 ...</PRE></DIV></DIV>
<P>　　在 [ 與 ] 之間，也可以放置其它的變數值，例如：</P>
<DIV class=code style="BORDER-TOP-STYLE: solid; BORDER-RIGHT-STYLE: solid; BORDER-LEFT-STYLE: solid; BORDER-BOTTOM-STYLE: solid">
<DIV class=codeContent><PRE class=code-java>...
 &lt;f:view&gt;
    &lt;h:outputText value=<SPAN class=code-quote>"#{someBean.someMap[user.name]}"</SPAN>/&gt; 
 &lt;/f:view&gt;
 ...</PRE></DIV></DIV>
<P>　　如果變數是List型態或陣列的話，則可以在 [] 中指定索引，例如：</P>
<DIV class=code style="BORDER-TOP-STYLE: solid; BORDER-RIGHT-STYLE: solid; BORDER-LEFT-STYLE: solid; BORDER-BOTTOM-STYLE: solid">
<DIV class=codeContent><PRE class=code-java>....
 &lt;f:view&gt;
     &lt;h:outputText value=<SPAN class=code-quote>"#{someBean.someList[0]}"</SPAN>/&gt; 
     &lt;h:outputText value=<SPAN class=code-quote>"#{someBean.someArray[1]}"</SPAN>/&gt;
     &lt;h:outputText
           value=<SPAN class=code-quote>"#{someBean.someListOrArray[user.age]}"</SPAN>/&gt;  
 &lt;/f:view&gt;
 ....</PRE></DIV></DIV>
<P>　　您也可以指定字面常數，對於true、false、字串、數字，JSF EL會嘗試進行轉換，例如：</P>
<DIV class=code style="BORDER-TOP-STYLE: solid; BORDER-RIGHT-STYLE: solid; BORDER-LEFT-STYLE: solid; BORDER-BOTTOM-STYLE: solid">
<DIV class=codeContent><PRE class=code-java>....
 &lt;h:outputText value=<SPAN class=code-quote>"#{<SPAN class=code-keyword>true</SPAN>}"</SPAN>/&gt;
 ....

 &lt;h:outputText value=<SPAN class=code-quote>"#{'This is a test'}"</SPAN>/&gt;
 ....</PRE></DIV></DIV>
<P>　　如果要輸出字串，必須以單引號 ' 或雙引數 " 括住，如此才不會被認為是變數名稱。</P>
<P>　　在宣告變數名稱時，要留意不可與JSF的保留字或關鍵字同名，例如不可取以下這些名稱：</P>
<DIV class=code style="BORDER-TOP-STYLE: solid; BORDER-RIGHT-STYLE: solid; BORDER-LEFT-STYLE: solid; BORDER-BOTTOM-STYLE: solid">
<DIV class=codeContent><PRE class=code-java><SPAN class=code-keyword>true</SPAN> <SPAN class=code-keyword>false</SPAN> <SPAN class=code-keyword>null</SPAN> div mod and or not eq ne lt gt le ge <SPAN class=code-keyword>instanceof</SPAN> empty</PRE></DIV></DIV>
<P>　　使用EL，您可以直接實行一些算術運算、邏輯運算與關係運算，其使用就如同在一般常見的程式語言中之運算。</P>
<P>　　算術運算子有：加法 (+), 減法 (-), 乘法 (*), 除法 (/ or div) 與餘除 (% or mod) 。下面是算術運算的一些例子：</P>
<TABLE class=confluenceTable>
<TBODY>
<TR>
<TH class=confluenceTh>運算式</TH>
<TH class=confluenceTh>結果</TH></TR>
<TR>
<TD class=confluenceTd>#{1}</TD>
<TD class=confluenceTd>1</TD></TR>
<TR>
<TD class=confluenceTd>#{1 + 2}</TD>
<TD class=confluenceTd>3</TD></TR>
<TR>
<TD class=confluenceTd>#{1.2 + 2.3}</TD>
<TD class=confluenceTd>3.5</TD></TR>
<TR>
<TD class=confluenceTd>#{1.2E4 + 1.4}</TD>
<TD class=confluenceTd>12001.4</TD></TR>
<TR>
<TD class=confluenceTd>#{-4 - 2}</TD>
<TD class=confluenceTd>-6</TD></TR>
<TR>
<TD class=confluenceTd>#{21 * 2}</TD>
<TD class=confluenceTd>42</TD></TR>
<TR>
<TD class=confluenceTd>#{3/4}</TD>
<TD class=confluenceTd>0.75</TD></TR>
<TR>
<TD class=confluenceTd>#{3 div 4}</TD>
<TD class=confluenceTd>0.75，除法</TD></TR>
<TR>
<TD class=confluenceTd>#{3/0}</TD>
<TD class=confluenceTd>Infinity</TD></TR>
<TR>
<TD class=confluenceTd>#{10%4}</TD>
<TD class=confluenceTd>2</TD></TR>
<TR>
<TD class=confluenceTd>#{10 mod 4}</TD>
<TD class=confluenceTd>2，也是餘除</TD></TR>
<TR>
<TD class=confluenceTd>#{(1==2) ? 3 : 4}</TD>
<TD class=confluenceTd>4</TD></TR></TBODY></TABLE>
<P>　　如同在Java語法一樣 ( expression ? result1 : result2）是個三元運算，expression為true顯示result1，false顯示result2。</P>
<P>　　邏輯運算有：and(或&amp;&amp;)、or(或!!)、not(或!)。一些例子為：</P>
<TABLE class=confluenceTable>
<TBODY>
<TR>
<TH class=confluenceTh>運算式</TH>
<TH class=confluenceTh>結果</TH></TR>
<TR>
<TD class=confluenceTd>#{true and false}</TD>
<TD class=confluenceTd>false</TD></TR>
<TR>
<TD class=confluenceTd>#{true or false}</TD>
<TD class=confluenceTd>true</TD></TR>
<TR>
<TD class=confluenceTd>#{not true}</TD>
<TD class=confluenceTd>false</TD></TR></TBODY></TABLE>
<P>　　關係運算有：小於Less-than (&lt; or lt)、大於Greater-than (&gt; or gt)、小於或等於Less-than-or-equal (&lt;= or le)、大於或等於Greater-than-or-equal (&gt;= or ge)、等於Equal (== or eq)、不等於Not Equal (!= or ne)，由英文名稱可以得到lt、gt等運算子之縮寫詞，以下是Tomcat的一些例子：</P>
<TABLE class=confluenceTable>
<TBODY>
<TR>
<TH class=confluenceTh>運算式</TH>
<TH class=confluenceTh>結果</TH></TR>
<TR>
<TD class=confluenceTd>#{1 &lt; 2}</TD>
<TD class=confluenceTd>true</TD></TR>
<TR>
<TD class=confluenceTd>#{1 lt 2}</TD>
<TD class=confluenceTd>true</TD></TR>
<TR>
<TD class=confluenceTd>#{1 &gt; (4/2)}</TD>
<TD class=confluenceTd>false</TD></TR>
<TR>
<TD class=confluenceTd>#{1 &gt; (4/2)}</TD>
<TD class=confluenceTd>false</TD></TR>
<TR>
<TD class=confluenceTd>#{4.0 &gt;= 3}</TD>
<TD class=confluenceTd>true</TD></TR>
<TR>
<TD class=confluenceTd>#{4.0 ge 3}</TD>
<TD class=confluenceTd>true</TD></TR>
<TR>
<TD class=confluenceTd>#{4 &lt;= 3}</TD>
<TD class=confluenceTd>false</TD></TR>
<TR>
<TD class=confluenceTd>#{4 le 3}</TD>
<TD class=confluenceTd>false</TD></TR>
<TR>
<TD class=confluenceTd>#{100.0 == 100}</TD>
<TD class=confluenceTd>true</TD></TR>
<TR>
<TD class=confluenceTd>#{100.0 eq 100}</TD>
<TD class=confluenceTd>true</TD></TR>
<TR>
<TD class=confluenceTd>#{(10*10) != 100}</TD>
<TD class=confluenceTd>false</TD></TR>
<TR>
<TD class=confluenceTd>#{(10*10) ne 100}</TD>
<TD class=confluenceTd>false</TD></TR></TBODY></TABLE>
<P>　　左邊是運算子的使用方式，右邊的是運算結果，關係運算也可以用來比較字元或字串，按字典順序來決定比較結果，例如：</P>
<TABLE class=confluenceTable>
<TBODY>
<TR>
<TH class=confluenceTh>運算式</TH>
<TH class=confluenceTh>結果</TH></TR>
<TR>
<TD class=confluenceTd>#{'a' &lt; 'b'}</TD>
<TD class=confluenceTd>true</TD></TR>
<TR>
<TD class=confluenceTd>#{'hip' &gt; 'hit'}</TD>
<TD class=confluenceTd>false</TD></TR>
<TR>
<TD class=confluenceTd>#{'4' &gt; 3}</TD>
<TD class=confluenceTd>true</TD></TR></TBODY></TABLE>
<P>　　EL運算子的執行優先順序與Java運算子對應，如果有疑慮的話，也可以使用括號()來自行決定先後順序。</P><!--
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
         xmlns:dc="http://purl.org/dc/elements/1.1/"
         xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
<rdf:Description
    rdf:about="http://www.javaworld.com.tw/confluence/display/J2EE/JSF+Expression+Language"
    dc:identifier="http://www.javaworld.com.tw/confluence/display/J2EE/JSF+Expression+Language"
    dc:title="JSF Expression Language"
    trackback:ping="http://www.javaworld.com.tw/confluence/rpc/trackback/2657"/>
</rdf:RDF>
--><!--
    Root decorator: all decisions about how a page is to be decorated via the
                    inline decoration begins here.
--><!--
    Switch based upon the context. However, for now, just delegate to a decorator
    identified directly by the context.
--><img src ="http://www.blogjava.net/RR00/aggbug/10736.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/RR00/" target="_blank">R.Zeus</a> 2005-08-22 21:32 <a href="http://www.blogjava.net/RR00/articles/10736.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>導航規則設置</title><link>http://www.blogjava.net/RR00/articles/10735.html</link><dc:creator>R.Zeus</dc:creator><author>R.Zeus</author><pubDate>Mon, 22 Aug 2005 13:30:00 GMT</pubDate><guid>http://www.blogjava.net/RR00/articles/10735.html</guid><wfw:comment>http://www.blogjava.net/RR00/comments/10735.html</wfw:comment><comments>http://www.blogjava.net/RR00/articles/10735.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/RR00/comments/commentRss/10735.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/RR00/services/trackbacks/10735.html</trackback:ping><description><![CDATA[在JSF中是根據faces-config.xml中&lt;navigation-rule&gt;設定，以決定在符合的條件成立時，該連結至哪一個頁面，一個基本的設定如下：
<DIV class=code style="BORDER-TOP-STYLE: solid; BORDER-RIGHT-STYLE: solid; BORDER-LEFT-STYLE: solid; BORDER-BOTTOM-STYLE: solid">
<DIV class=codeContent><PRE class=code-java>....
    &lt;navigation-rule&gt;
        &lt;from-view-id&gt;/pages/index.jsp&lt;/from-view-id&gt;
        &lt;navigation-<SPAN class=code-keyword>case</SPAN>&gt;
            &lt;from-outcome&gt;success&lt;/from-outcome&gt;
            &lt;to-view-id&gt;/pages/welcome.jsp&lt;/to-view-id&gt;
        &lt;/navigation-<SPAN class=code-keyword>case</SPAN>&gt;
        &lt;navigation-<SPAN class=code-keyword>case</SPAN>&gt;
            &lt;from-outcome&gt;failure&lt;/from-outcome&gt;
            &lt;to-view-id&gt;/pages/index.jsp&lt;/to-view-id&gt;
        &lt;/navigation-<SPAN class=code-keyword>case</SPAN>&gt;
    &lt;/navigation-rule&gt;
 ....</PRE></DIV></DIV>
<P>　　對於JSF，每一個視圖（View）都有一個獨特的識別（identifier），稱之為View ID，在JSF中的View ID是從Web應用程式的環境相對路徑開始計算，設定時都是以/作為開頭，如果您請求時的路徑是/pages/index.faces，則JSF會將副檔名改為/pages/index.jsp，以此作為view-id。</P>
<P>　　在&lt;navigation-rule&gt;中的&lt;from-view-id&gt;是個選擇性的定義，它規定了來源頁面的條件，&lt;navigation-case&gt;中定義各種導覽條件，&lt;from-outcome&gt;定義當表單結果符合的條件時，各自改導向哪一個目的頁面，目的頁面是在&lt;to-view-id&gt;中定義。</P>
<P>　　您還可以在&lt;navigation-case&gt;中加入&lt;from-action&gt;，進一步規範表單結果必須根據哪一個動作方法（action method），當中是使用 JSF Expression Language 來設定，例如：</P>
<DIV class=code style="BORDER-TOP-STYLE: solid; BORDER-RIGHT-STYLE: solid; BORDER-LEFT-STYLE: solid; BORDER-BOTTOM-STYLE: solid">
<DIV class=codeContent><PRE class=code-java>....
    &lt;navigation-rule&gt;
        &lt;from-view-id&gt;/pages/index.jsp&lt;/from-view-id&gt;
        &lt;navigation-<SPAN class=code-keyword>case</SPAN>&gt;
            &lt;from-action&gt;#{user.verify}&lt;/from-action&gt;
            &lt;from-outcome&gt;success&lt;/from-outcome&gt;
            &lt;to-view-id&gt;/pages/welcome.jsp&lt;/to-view-id&gt;
        &lt;/navigation-<SPAN class=code-keyword>case</SPAN>&gt;
        ....
    &lt;/navigation-rule&gt;
 ....</PRE></DIV></DIV>
<P>　　在導航時，預設都是使用forward的方式，您可以在&lt;navigation-case&gt;中加入一個&lt;redirect/&gt;，讓JSF發出讓瀏覽器重新導向（redirect）的header，讓瀏覽器主動要求新網頁，例如：</P>
<DIV class=code style="BORDER-TOP-STYLE: solid; BORDER-RIGHT-STYLE: solid; BORDER-LEFT-STYLE: solid; BORDER-BOTTOM-STYLE: solid">
<DIV class=codeContent><PRE class=code-java>....
    &lt;navigation-rule&gt;
        &lt;from-view-id&gt;/pages/index.jsp&lt;/from-view-id&gt;
        &lt;navigation-<SPAN class=code-keyword>case</SPAN>&gt;
            &lt;from-outcome&gt;success&lt;/from-outcome&gt;
            &lt;to-view-id&gt;/pages/welcome.jsp&lt;/to-view-id&gt;
            &lt;redirect/&gt;
        &lt;/navigation-<SPAN class=code-keyword>case</SPAN>&gt;
        ....
    &lt;/navigation-rule&gt;
 ....</PRE></DIV></DIV>
<P>您的來源網頁可能是某個特定模組，例如在/admin/下的頁面，您可以在&lt;from-view-id&gt;中使用wildcards，也就是使用 * 字元，例如：</P>
<DIV class=code style="BORDER-TOP-STYLE: solid; BORDER-RIGHT-STYLE: solid; BORDER-LEFT-STYLE: solid; BORDER-BOTTOM-STYLE: solid">
<DIV class=codeContent><PRE class=code-java>....
    &lt;navigation-rule&gt;
        &lt;from-view-id&gt;/admin/*&lt;/from-view-id&gt;
        &lt;navigation-<SPAN class=code-keyword>case</SPAN>&gt;
            &lt;from-action&gt;#{user.verify}&lt;/from-action&gt;
            &lt;from-outcome&gt;success&lt;/from-outcome&gt;
            &lt;to-view-id&gt;/pages/welcome.jsp&lt;/to-view-id&gt;
        &lt;/navigation-<SPAN class=code-keyword>case</SPAN>&gt;
        ....
    &lt;/navigation-rule&gt;
 ....</PRE></DIV></DIV>
<P>在上面的設定中，只要來源網頁是從/admin來的，都可以開始測試接下來的&lt;navigation-case&gt;。</P>
<P>　　&lt;from-view-id&gt;如果沒有設定，表示來源網頁不作限制，您也可以使用 * 顯式的在定義檔中表明，例如：</P>
<DIV class=code style="BORDER-TOP-STYLE: solid; BORDER-RIGHT-STYLE: solid; BORDER-LEFT-STYLE: solid; BORDER-BOTTOM-STYLE: solid">
<DIV class=codeContent><PRE class=code-java>....
    &lt;navigation-rule&gt;
        &lt;from-view-id&gt;/*&lt;/from-view-id&gt;
        &lt;navigation-<SPAN class=code-keyword>case</SPAN>&gt;
        ....
    &lt;/navigation-rule&gt;
 ....</PRE></DIV></DIV>
<P>或者是這樣：</P>
<DIV class=code style="BORDER-TOP-STYLE: solid; BORDER-RIGHT-STYLE: solid; BORDER-LEFT-STYLE: solid; BORDER-BOTTOM-STYLE: solid">
<DIV class=codeContent><PRE class=code-java>....
    &lt;navigation-rule&gt;
        &lt;from-view-id&gt;*&lt;/from-view-id&gt;
        &lt;navigation-<SPAN class=code-keyword>case</SPAN>&gt;
        ....
    &lt;/navigation-rule&gt;
 ....</PRE></DIV></DIV><img src ="http://www.blogjava.net/RR00/aggbug/10735.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/RR00/" target="_blank">R.Zeus</a> 2005-08-22 21:30 <a href="http://www.blogjava.net/RR00/articles/10735.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JSF 入门</title><link>http://www.blogjava.net/RR00/articles/10733.html</link><dc:creator>R.Zeus</dc:creator><author>R.Zeus</author><pubDate>Mon, 22 Aug 2005 13:22:00 GMT</pubDate><guid>http://www.blogjava.net/RR00/articles/10733.html</guid><wfw:comment>http://www.blogjava.net/RR00/comments/10733.html</wfw:comment><comments>http://www.blogjava.net/RR00/articles/10733.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/RR00/comments/commentRss/10733.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/RR00/services/trackbacks/10733.html</trackback:ping><description><![CDATA[转自：<A href="http://www.javaworld.com.tw/confluence/pages/viewpage.action?pageId=2630">http://www.javaworld.com.tw/confluence/pages/viewpage.action?pageId=2630</A><BR><BR>請至 JSF 官方網站的 <SPAN class=nobr><A title="Visit page outside Confluence" href="http://java.sun.com/j2ee/javaserverfaces/download.html" rel=nofollow>下載區<SUP><IMG class=rendericon height=7 alt="" src="http://www.javaworld.com.tw/confluence/images/icons/linkext7.gif" width=7 align=absMiddle border=0></SUP></A></SPAN> 下載參考實作，在下載壓縮檔並解壓縮之後，將其 lib 目錄下的 jar 檔案複製至您的Web應用程式的/WEB-INF/lib目錄下，另外您還需要 jstl.jar 與 standard.jar 檔案，這些檔案您可以在 sample 目錄下，解壓縮當中的一個範例，在它的/WEB-INF/lib目錄下找到，將之一併複製至您的Web應用程式的/WEB-INF/lib目錄下，您總共需要以下的檔案： 
<DIV class=code style="BORDER-TOP-STYLE: solid; BORDER-RIGHT-STYLE: solid; BORDER-LEFT-STYLE: solid; BORDER-BOTTOM-STYLE: solid">
<DIV class=codeContent><PRE class=code-java>* jsf-impl.jar
    * jsf-api.jar
    * commons-digester.jar
    * commons-collections.jar
    * commons-beanutils.jar
    * jstl.jar
    * standard.jar</PRE></DIV></DIV>
<P>　　接下來配置Web應用程式的web.xml，使用JSF時，所有的請求都透過FacesServlet來處理，您可以如下定義：</P>
<P><BR clear=all></P>
<UL>
<LI>web.xml </LI></UL>
<DIV class=code style="BORDER-TOP-STYLE: solid; BORDER-RIGHT-STYLE: solid; BORDER-LEFT-STYLE: solid; BORDER-BOTTOM-STYLE: solid">
<DIV class=codeHeader style="BORDER-BOTTOM-STYLE: solid"><B>web.xml</B></DIV>
<DIV class=codeContent><PRE class=code-java>&lt;?xml version=<SPAN class=code-quote>"1.0"</SPAN> encoding=<SPAN class=code-quote>"ISO-8859-1"</SPAN>?&gt;
 &lt;web-app xmlns=<SPAN class=code-quote>"http:<SPAN class=code-comment>//java.sun.com/xml/ns/j2ee"</SPAN>
</SPAN>    xmlns:xsi=<SPAN class=code-quote>"http:<SPAN class=code-comment>//www.w3.org/2001/XMLSchema-instance"</SPAN>
</SPAN>    xsi:schemaLocation="http:<SPAN class=code-comment>//java.sun.com/xml/ns/j2ee 
</SPAN>    http:<SPAN class=code-comment>//java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
</SPAN>    version=<SPAN class=code-quote>"2.4"</SPAN>&gt;
 
    &lt;description&gt;
        JSF Demo
    &lt;/description&gt;
    &lt;display-name&gt;JSF Demo&lt;/display-name&gt;
    &lt;servlet&gt;
        &lt;servlet-name&gt;Faces Servlet&lt;/servlet-name&gt;
        &lt;servlet-class&gt;
            javax.faces.webapp.FacesServlet
        &lt;/servlet-class&gt;
        &lt;load-on-startup&gt;1&lt;/load-on-startup&gt;
    &lt;/servlet&gt;
   
    &lt;servlet-mapping&gt;
        &lt;servlet-name&gt;Faces Servlet&lt;/servlet-name&gt;
        &lt;url-pattern&gt;*.faces&lt;/url-pattern&gt;
    &lt;/servlet-mapping&gt;
   
    &lt;welcome-file-list&gt;
        &lt;welcome-file&gt;index.html&lt;/welcome-file&gt;
    &lt;/welcome-file-list&gt;
 &lt;/web-app&gt;</PRE></DIV></DIV>
<P>　　在上面的定義中，我們將所有.faces的請求交由FaceServlet來處理，FaceServlet會喚起相對的.jsp網頁，例如請求是/index.faces的話，則實際上會喚起/index.jsp網頁，完成以上的配置，您就可以開始使用JSF了。<BR></P>
<P>先看看應用程式開發人員要作些什麼事，我們撰寫一個簡單的JavaBean：</P>
<DIV class=code style="BORDER-TOP-STYLE: solid; BORDER-RIGHT-STYLE: solid; BORDER-LEFT-STYLE: solid; BORDER-BOTTOM-STYLE: solid">
<DIV class=codeHeader style="BORDER-BOTTOM-STYLE: solid"><B>UserBean.java</B></DIV>
<DIV class=codeContent><PRE class=code-java><SPAN class=code-keyword>package</SPAN> onlyfun.caterpillar;

 <SPAN class=code-keyword>public</SPAN> class UserBean {
    <SPAN class=code-keyword>private</SPAN> <SPAN class=code-object>String</SPAN> name;
   
    <SPAN class=code-keyword>public</SPAN> void setName(<SPAN class=code-object>String</SPAN> name) {
        <SPAN class=code-keyword>this</SPAN>.name = name;
    }
   
    <SPAN class=code-keyword>public</SPAN> <SPAN class=code-object>String</SPAN> getName() {
        <SPAN class=code-keyword>return</SPAN> name;
    }
 }</PRE></DIV></DIV>
<P>　　這個Bean將儲存使用者的名稱，編譯好之後放置在/WEB-INF/classes下。</P>
<P>　　接下來設計頁面流程，我們將先顯示一個登入網頁/pages/index.jsp，使用者填入名稱並送出表單，之後在/pages/welcome.jsp中顯示Bean中的使用者名稱與歡迎訊息。</P>
<P>　　為了讓JSF知道我們所設計的Bean以及頁面流程，我們定義一個/WEB-INF/faces-config.xml：</P>
<DIV class=code style="BORDER-TOP-STYLE: solid; BORDER-RIGHT-STYLE: solid; BORDER-LEFT-STYLE: solid; BORDER-BOTTOM-STYLE: solid">
<DIV class=codeHeader style="BORDER-BOTTOM-STYLE: solid"><B>faces-config.xml</B></DIV>
<DIV class=codeContent><PRE class=code-java>&lt;?xml version=<SPAN class=code-quote>"1.0"</SPAN>?&gt;
 &lt;!DOCTYPE faces-config PUBLIC
 <SPAN class=code-quote>"-<SPAN class=code-comment>//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.0//EN"</SPAN>
</SPAN> <SPAN class=code-quote>"http:<SPAN class=code-comment>//java.sun.com/dtd/web-facesconfig_1_0.dtd"</SPAN>&gt;
</SPAN>
 &lt;faces-config&gt;
    &lt;navigation-rule&gt;
        &lt;from-view-id&gt;/pages/index.jsp&lt;/from-view-id&gt;
        &lt;navigation-<SPAN class=code-keyword>case</SPAN>&gt;
            &lt;from-outcome&gt;login&lt;/from-outcome&gt;
            &lt;to-view-id&gt;/pages/welcome.jsp&lt;/to-view-id&gt;
        &lt;/navigation-<SPAN class=code-keyword>case</SPAN>&gt;
    &lt;/navigation-rule&gt;
       
    &lt;managed-bean&gt;
        &lt;managed-bean-name&gt;user&lt;/managed-bean-name&gt;
         &lt;managed-bean-class&gt;
             onlyfun.caterpillar.UserBean
         &lt;/managed-bean-class&gt;
        &lt;managed-bean-scope&gt;session&lt;/managed-bean-scope&gt;
    &lt;/managed-bean&gt;
 &lt;/faces-config&gt;</PRE></DIV></DIV>
<P>　　在&lt;navigation-rule&gt;中，我們定義了頁面流程，當請求來自&lt;from-view- id&gt;中指定的頁面，並且指定了&lt;navigation-case&gt;中的&lt;from-outcome&gt;為login時，則會將請求導向至&lt;to-view-id&gt;所指定的頁面。</P>
<P>　　在&lt;managed-bean&gt;中我們可以統一管理我們的Bean，我們設定Bean物件的存活範圍是session，也就是使用者開啟瀏覽器與程式互動過程中都存活。</P>
<P>　　接下來要告訴網頁設計人員的資訊是，他們可以使用的Bean名稱，即&lt;managed-bean-name&gt;中設定的名稱，以及上面所定義的頁面流程。</P>
<H2><A name=%E7%AC%AC%E4%B8%80%E5%80%8BJSF%E7%A8%8B%E5%BC%8F-%E7%B6%B2%E9%A0%81%E8%A8%AD%E8%A8%88%E4%BA%BA%E5%93%A1>網頁設計人員</A></H2>
<P>　　首先網頁設計人員撰寫index.jsp網頁：</P>
<DIV class=code style="BORDER-TOP-STYLE: solid; BORDER-RIGHT-STYLE: solid; BORDER-LEFT-STYLE: solid; BORDER-BOTTOM-STYLE: solid">
<DIV class=codeHeader style="BORDER-BOTTOM-STYLE: solid"><B>index.jsp</B></DIV>
<DIV class=codeContent><PRE class=code-java>&lt;%@taglib uri=<SPAN class=code-quote>"http:<SPAN class=code-comment>//java.sun.com/jsf/core"</SPAN> prefix=<SPAN class=code-quote>"f"</SPAN> %&gt;
</SPAN> &lt;%@taglib uri=<SPAN class=code-quote>"http:<SPAN class=code-comment>//java.sun.com/jsf/html"</SPAN> prefix=<SPAN class=code-quote>"h"</SPAN> %&gt;
</SPAN> &lt;%@page contentType=<SPAN class=code-quote>"text/html;charset=Big5"</SPAN>%&gt; 
 &lt;html&gt;
 &lt;head&gt;
 &lt;title&gt;第一個JSF程式&lt;/title&gt;
 &lt;/head&gt;
 &lt;body&gt;
    &lt;f:view&gt;
        &lt;h:form&gt;
            &lt;h3&gt;請輸入您的名稱&lt;/h3&gt;
            名稱: &lt;h:inputText value<FONT style="BACKGROUND-COLOR: #deb887">=<SPAN class=code-quote>"#{user.name}"</SPAN>/</FONT>&gt;&lt;p&gt;
            &lt;h:commandButton value=<SPAN class=code-quote>"送出"</SPAN> action=<SPAN class=code-quote>"<FONT style="BACKGROUND-COLOR: #deb887">login</FONT>"</SPAN>/&gt;
        &lt;/h:form&gt;
    &lt;/f:view&gt;
 &lt;/body&gt;
 &lt;/html&gt;</PRE></DIV></DIV>
<P>　　我們使用了JSF的core與html標籤庫，core是有關於UI元件的處理，而html則是有關於HTML的進階標籤。</P>
<P>　　&lt;f:view&gt;與&lt;html&gt;有類似的作用，當您要開始使用JSF元件時，這些元件一定要在&lt;f: view&gt;與&lt;/f:view&gt;之間，就如同使用HTML時，所有的標籤一定要在&lt;html&gt;與&lt; /html&gt;之間。</P>
<P>　　html標籤庫中幾乎都是與HTML標籤相關的進階標籤，&lt;h:form&gt;會產生一個表單，我們使用&lt;h: inputText&gt;來顯示user這個Bean物件的name屬性，而&lt;h:commandButton&gt;會產生一個提交按鈕，我們在action屬性中指定將根據之前定義的login頁面流程中前往welcome.jsp頁面。</P>
<P>　　網頁設計人員不必理會表單傳送之後要作些什麼，他只要設計好歡迎頁面就好了：</P>
<DIV class=code style="BORDER-TOP-STYLE: solid; BORDER-RIGHT-STYLE: solid; BORDER-LEFT-STYLE: solid; BORDER-BOTTOM-STYLE: solid">
<DIV class=codeHeader style="BORDER-BOTTOM-STYLE: solid"><B>welcome.jsp</B></DIV>
<DIV class=codeContent><PRE class=code-java>&lt;%@ taglib uri=<SPAN class=code-quote>"http:<SPAN class=code-comment>//java.sun.com/jsf/core"</SPAN> prefix=<SPAN class=code-quote>"f"</SPAN> %&gt;
</SPAN> &lt;%@ taglib uri=<SPAN class=code-quote>"http:<SPAN class=code-comment>//java.sun.com/jsf/html"</SPAN> prefix=<SPAN class=code-quote>"h"</SPAN> %&gt;
</SPAN> &lt;%@page contentType=<SPAN class=code-quote>"text/html;charset=Big5"</SPAN>%&gt; 
 &lt;html&gt;
 &lt;head&gt;
 &lt;title&gt;第一個JSF程式&lt;/title&gt;
 &lt;/head&gt;
 &lt;body&gt;
    &lt;f:view&gt;
        &lt;h:outputText value<FONT style="BACKGROUND-COLOR: #deb887">=<SPAN class=code-quote>"#{user.name}"</SPAN>/</FONT>&gt; 您好！
        &lt;h3&gt;歡迎使用 JavaServer Faces！&lt;/h3&gt;
    &lt;/f:view&gt;
 &lt;/body&gt;
 &lt;/html&gt;</PRE></DIV></DIV>
<P>　　這個頁面沒什麼需要解釋的了，如您所看到的，在網頁上沒有程式邏輯，網頁設計人員所作的就是遵照頁面流程，使用相關名稱取出資料，而不用擔心實際上程式是如何運作的。</P>
<P>　　接下來啟動Container，連接上您的應用程式網址，例如：http://localhost:8080/jsfDemo/pages/index.faces，填入名稱並送出表單，您的歡迎頁面就會顯示了。</P><!--
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
         xmlns:dc="http://purl.org/dc/elements/1.1/"
         xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
<rdf:Description
    rdf:about="http://www.javaworld.com.tw/confluence/pages/viewpage.action?pageId=2644"
    dc:identifier="http://www.javaworld.com.tw/confluence/pages/viewpage.action?pageId=2644"
    dc:title="第一個JSF程式"
    trackback:ping="http://www.javaworld.com.tw/confluence/rpc/trackback/2644"/>
</rdf:RDF>
--><!--
    Root decorator: all decisions about how a page is to be decorated via the
                    inline decoration begins here.
--><!--
    Switch based upon the context. However, for now, just delegate to a decorator
    identified directly by the context.
--><!--
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
         xmlns:dc="http://purl.org/dc/elements/1.1/"
         xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
<rdf:Description
    rdf:about="http://www.javaworld.com.tw/confluence/pages/viewpage.action?pageId=2628"
    dc:identifier="http://www.javaworld.com.tw/confluence/pages/viewpage.action?pageId=2628"
    dc:title="簡介JSF"
    trackback:ping="http://www.javaworld.com.tw/confluence/rpc/trackback/2628"/>
</rdf:RDF>
--><!--
    Root decorator: all decisions about how a page is to be decorated via the
                    inline decoration begins here.
--><!--
    Switch based upon the context. However, for now, just delegate to a decorator
    identified directly by the context.
--><img src ="http://www.blogjava.net/RR00/aggbug/10733.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/RR00/" target="_blank">R.Zeus</a> 2005-08-22 21:22 <a href="http://www.blogjava.net/RR00/articles/10733.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>