级别: 初级 Eugene Konstantinov (ekonstan@ie.ibm.com), 软件工程师, IBM Ireland
2004 年 11 月 01 日 本文描述了集成到 WebSphere Studio V5.1.2 中的 IBM Extended JavaServer Faces 组件的 Fileupload/Download 特性。用户可以使用这些组件和附带的快速应用程序开发 (rapid application development,RAD) 工具来构建用于上传内容并显示的 Web 应用程序。本文利用 Websphere Service Data Object (SDO) 技术显示了如何使 Faces 组件与数据协同工作。
引言
IBM® WebSphere® Studio V5.1.2 包含基于最近发布的 JavaServer Faces 技术 (JSR 127) 的一套组件。这些组件已经在 Websphere Studio V5.1.1 中出现过,然后被重新加工,添加了新的特性和扩展功能。本文详细阐述了如何使用 Fileupload/Download 组件创建更丰富的用户界面。
在本文中,我们将引入一个带有简单 JSP 页面的 JSF Web 项目,该项目演示了运行中的 Fileupload/Download 组件。然后我们将研究那些页面并讨论组件的使用场景。最后,我们将讨论下载组件在数据表内的使用场景。
创建新的 web 项目并导入文中所使用的资源
在开始之前,确保您能够访问 DB2 服务器,因为我们将要创建一个新表。
- 在本文末尾
下载
photoalbum.war
文件。
- 选择
File => Import => WAR file 开始导入
photoalbum.war 到新的动态 WEB 项目中。
- 找到下载的 WAR 文件。
- 单击
New 创建新的动态项目。
- 单击
Next 然后输入
PhotoAlbum 作为项目的名称。
- 选中
Configure advanced options。
- 单击
Next 两次直到出现 Feature 页面,然后选中
WDO Relational database runtime。
- 单击
Finish,创建 Web 项目。
- 再次单击
Finish,导入源页面和配置文件。
创建新的数据表
- 转到
PhotoAlbum 项目的
dbsetup 文件夹。
- 右键单击
dbsetup.sql,选择
Run on Database Server。
- 通过向导页面,提供运行脚本所需的选项。
确认已经创建了 PHOTO 表
- 转到 Data 视图,找到 DB Servers 视图。
- 选择一个以前创建的到 PHOTO 表的连接 (Con1)
- 右键单击并选择
Refresh。您应该可以看到表已经创建。
重建项目中的数据库连接
- 在 Web 视图中,打开 PhotoAlbum 项目中的
upload.jsp。
- 转到 Page Data 试图,双击
new_rec SDO 记录。
- 转到 Connections 选项卡,然后单击
Development connection details 的
Edit 按钮。
- 选择
Existing live connections,然后单击
Next。
- 选择您先前创建的连接 (Con1),然后单击
Finish。
- 重新编译项目。
Fileupload 组件
特性描述
用户使用 Fileupload 组件从客户端上载数据到服务器。运行的时候发送一个
<input type="file"/> HTML 标签。提交表单的 Content-Type 属性会自动设置为
multipart/form-data。
 |
Fileupload 组件的特性
- 利用相应的
hx:fileupload 标签上载文件。
- 呈现类型文件的标准 HTML 输入标签。
- 接受 Websphere SDO 作为数据模型。
- 接受 JavaBeans 作为数据模型,支持
byte[], java.lang.String, java.io.OutputStream。
- 可以选择是存储上传条目的文件名还是 mime 类型(
hx:fileProp 标签)。
- 通过 mime 类型或文件扩展名(接受和拒绝属性)限制上传条目。
- 如果上传不正确类型的数据,将给出一个验证错误消息。
|
|
图 1. 如何在运行的时候呈现 Fileupload 组件
步骤 1. 服务器端的运行体验
项目中的
upload.jsp 页面演示了组件的使用。通过在 navigator 浏览器中选择该页面,查看它的运行,并在 WebSphere V5.1 Test Server 上运行。一旦服务器启动并运行,您将看到如下的屏幕:
图 2. upload.jsp 页面的输出
让我们来仔细看一下这个组件是如何工作的:
代码片段 1. 带有
hx:fileupload 标签的
upload.jsp 文件
...
<hx:fileupload styleClass="fileupload" id="fileupload1"
value="#{pc_Upload.new_rec.PHOTO}" accept="image/*">
<hx:fileProp name="fileName" value="#{pc_Upload.new_rec.FILENAME}" />
<hx:fileProp name="contentType" value="#{pc_Upload.new_rec.FILETYPE}" />
</hx:fileupload>
... |
我们可以看到,Fileupload 组件有一个相应的
hx:fileupload 标签,通过其属性值该标签可以与模型绑定。 绑定值 exClickion
"#{pc_Upload.new_rec.PHOTO}" 建立了一个到 WebSphere SDO(关系记录)的连接,这个 WebSphere SDO 被映射到我们表中 BLOB 类型的
PHOTO 列。更准确的说,exClickion
pc_Upload 引用代表 upload.jsp 页面代码的管理 bean。
new_rec 是页面代码 bean 的一个属性,代表一条 SDO 记录,而
PHOTO 是映射到表中 PHOTO 列 (BLOB) 的 SDO 对象的一个属性。
 |
新特性:
hx:fileProp tag
在 Websphere Studio V.5.1.1 中,没有嵌套的
hx:fileProp 标签。属性信息保存在 BLOB 自身中,这使得数据只对 IBM 组件是可读的。
|
|
accept=image/* 属性说明只能上载图象,否则会显示错误信息。最后,需要两个
hx:fileProp 标签来说明同一个表中上载条目的额外信息。没有这个元信息,上载的数据可能会无效。因此,如果能上载任意类型的数据,那么保存关于文件名和 mime 类型的信息是很重要的。
excluded="comma-delimited-list-of-extensions" 属性很少使用,而且只在 Windows 系统下有意义。当试图提交和该属性值中列出的扩展名一致的文件时,该属性将抛出一个错误。例如,
excluded="exe,bat" 说明不允许上载 exe 和 bat 文件。
下载组件
 |
下载组件列表
- hx:graphicImageEx
- hx:outputLinkEx
- hx:playerGenericPlayer
- hx:playerFlash
- hx:playerMediaPlayer
- hx:playerShockwave
- hx:playerRealPlayer
一般特性
- 从后端服务器上下载数据到客户端
- 使用 Websphere SDO 作为数据模型
- 使用 JavaBeans 作为数据模型,支持
byte[],java.lang.String,java.io.InputStream
- 不依靠 HTTP 会话或服务器文件系统读取数值资源
|
|
步骤 2. 利用 Image 组件显示上载的图象
在 ID 文本框中输入一个数字,例如 1 并找到要上载的图象文件(最大为 150 KB)。确保该图象文件的类型有效(.jpg、.gif、 .bmp 等等)——否则将出现一个错误,提示文件类型无效。
尝试单击
Submit,将在表中插入一条新记录并导航到 display.jsp 页面,这里显示了上载的图象。
图 3. display.jsp 显示上传的图象
hx:graphicImageEx 标签处理上传的图象并从表中下载上传的二进制字节。由于这个组件本身的特性,它总是处理下载。为正确识别图象的类型,它需要通过
"mimeType" 属性的帮助来传递信息,该属性还与值绑定 exClickions 协同工作。这里是帮助说明的代码片段:
代码片段 2. 带
hx:graphicImageEx tag 的
display.jsp
...
<hx:graphicImageEx id="imageEx1" value="#{pc_Display.disp_rec.PHOTO}"
styleClass="graphicImageEx"
mimeType="#{pc_Display.disp_rec.FILETYPE}" >
</hx:graphicImageEx>
... |
步骤 3. 向数据库提交更多的图象
在学习数据表内部的下载使用场景前,设法向表中上传更多的图象。只需要单击浏览器上的 Back 按纽,返回到
upload.jsp 页面,提交更多的文件。不要忘记指定唯一的 ID,否则将更新相同的记录,覆盖掉先前上传的图象。
数据表中的下载使用场景
数据表组件(以前称为 Datagrid)由可能包含其他组件的列组成。运行的时候,它显示数据模型中的记录,例如 Websphere SDO 列表。因此数据表可以通过元素列表进行迭代并且通过
var 属性定义的变量为子组件提供值。
下一部分将讨论数据表中与下载相关的问题。
默认使用场景
该场景由工具支持,这使其成为默认的场景。您所需要做的全部事情就是从面板中拖放下载组件到数据表列。
步骤 4. 在服务器上运行 download.jsp
尝试运行 download.jsp 页面来查看实例结果。
图 4. 带 hx:graphicImageEx 和 hx:outputLinkEx 的 Datatable
在该场景中,处理下载的组件使用父数据表组件的变量(var 属性定义的)。photos 是 SDO 列表并映射到 PHOTO 表。注意是如何设置
hx:graphicImageEx 和
hx:outputLinkEx 的属性值的(都标记为粗体):
代码片段 3. 使用数据表变量的 “download.jsp”
...
<h:dataTable id="table1" value="#{pc_Download.photos}"
var="varphotos" >
<h:column id="column1" >
<f:facet name="header">
<h:outputText value="Id" id="text1"></h:outputText>
</f:facet>
<h:outputText id="text2" value="#{varphotos.ID}" >
</h:outputText>
</h:column>
<h:column id="column2" >
<f:facet name="header">
<h:outputText value="Photo" id="text3"></h:outputText>
</f:facet>
<hx:graphicImageEx id="imageEx1"
value="#{varphotos.PHOTO}"
mimeType="#{varphotos.FILETYPE}"
</hx:graphicImageEx>
</h:column>
<h:column id="column3">
<f:facet name="header">
<h:outputText value="Download" id="text4"></h:outputText>
</f:facet>
<hx:outputLinkEx id="linkEx1"
value="#{varphotos.PHOTO}"
mimeType="#{varphotos.FILETYPE}">
<h:outputText id="text5" value="#{varphotos.FILENAME}"></h:outputText>
</hx:outputLinkEx>
</h:column>
</h:dataTable>
...
|
在该场景中,嵌套组件使用了父数据表中的 Websphere 记录列表。负面效应是将生成与数据表中显示的记录数目相同次数的下载请求。之所以产生负面效应是因为处理下载请求的 ValueResourcePhaseListener 对象在每次处理请求时都要实例化 Websphere 记录列表 (SDO 列表)。这样会使效率很低,当我们只需要获取一行时,事实上将获取数据表的所有行。这样当表中有大量记录时,将严重延迟记录的显示。
优点:
- 容易生成代码(从 Page Data View 中拖放 Datalist)
- 不需要创建额外的 Websphere SDO 记录
缺点:
步骤 5. 改进的使用场景:在服务器上运行 download_2.jsp
这次尝试运行 download_2.jsp。该页面显示了与 download.jsp 完全相同的结果。然而这次我们创建了一个额外的 SDO 记录,消除了默认场景的上述问题。因此任何下载组件都可以使用 SDO 记录来实现下载功能。 为了给那个 SDO 记录设置一个过滤条件,用户必须在下在组件上使用嵌套的
f:parameter 标签,标签上带有一个标识记录关键字的值。
代码片段 4. “download_2.jsp” 具有较高的数据访问效率
...
<h:dataTable id="table1" value="#{pc_Download_2.photos}" var="varphotos" >
<h:column id="column1" >
<f:facet name="header">
<h:outputText value="Id" id="text1"></h:outputText>
</f:facet>
<h:outputText id="text2" value="#{varphotos.ID}" >
</h:outputText>
</h:column>
<h:column id="column2" >
<f:facet name="header">
<h:outputText value="Photo" id="text3"></h:outputText>
</f:facet>
<hx:graphicImageEx id="imageEx1"
value="#{pc_Download_2.disp_rec2.PHOTO}"
mimeType="#{pc_Download_2.disp_rec2.FILETYPE}"
<f:param id="param1" name="ID" value="#{varphotos.ID}"></f:param>
</hx:graphicImageEx>
</h:column>
<h:column id="column3">
<f:facet name="header">
<h:outputText value="Download" id="text4"></h:outputText>
</f:facet>
<hx:outputLinkEx id="linkEx1"
value="#{pc_Download_2.disp_rec2.PHOTO}"
mimeType="#{pc_Download_2.disp_rec2.FILETYPE}">
<h:outputText id="text5" value="#{varphotos.FILENAME}"></h:outputText>
<f:param id="param2" name="ID" value="#{varphotos.ID}"></f:param>
</hx:outputLinkEx>
</h:column>
</h:dataTable>
...
|
优点:
缺点:
- 没有支持这种场景的默认工具
- 需要创建一条额外的 SDO 记录
结束语
本文描述了 Fileupload 和 Download 这两个扩展 JSF 组件。通过样本 Web 项目,阐述了如何利用他们来构建动态 Web 页面。本文还演示了 Datatable 组件中下载功能的使用。
下载 | 名字 | 大小 | 下载方法 |
|---|
| photoalbum.zip | 2.6 MB |
FTP | HTTP |
参考资料
关于作者  | 
|  |
Eugene Konstantinov 在 Websphere Studio RAD Tools 工作组工作,在 IBM 的都柏林软件试验室从事开发 Fileupload/Download 组件、Visual Editor
for Java 开放源码项目方面的工作。他是一位 Sun 认证的 Web 开发人员和 Java 开发人员。您可以通过
ekonstan@ie.ibm.com 与 Eugene 联系。
|
对本文的评价
|