首页 - Ajax专区 - 实例应用

AJAX+JSF组件实现高性能的文件上载

发布时间: 2007-03-19 12:35    作者: 未知    来源: 未知    浏览:    评论

ProgressMonitorFileItem把DiskFileItem的缺省OutputStream包装到一个BytesCountingOutputStream中,这可以在每次读取一定数目的字节后更新相关的ProgressObserver。

(五) 支持AJAX的JavaServer Faces(JSF)上传组件

这个组件负责生成HTML文件上传标签,显示一个进度条以监视文件上传,并且生成一旦文件上传成功需要被显示的组件。使用JavaServer Faces实现这个组件的一个主要优点是,大多数复杂性被隐藏起来。开发人员只需要把组件标签添加到JSP,而后由组件负责所有的AJAX及相关的进度条监控细节问题。下面的JSP代码片断用于把上传组件添加到页面上。

<comp:fileUpload

 value="#{uploadPageBean.uploadedFile}"

 uploadIcon="images/upload.png"

 styleClass="progressBarDiv"

 progressBarStyleClass="progressBar"

 cellStyleClass="progressBarCell"

 activeStyleClass="progressBarActiveCell">

<%--下面是一旦文件上传完成将成为可见的组件--%>

<h:panelGrid columns="2" cellpadding="2" cellspacing="0" width="100%">

<f:facet name="header">

<h:outputText styleClass="text"

value="文件上传成功." />

</f:facet>

<h:panelGroup style="text-align:left;display:block;width:100%;">

<h:commandButton action="#{uploadPageBean.reset}"

image="images/reset.png"/>

</h:panelGroup>

<h:panelGroup style="text-align:right;display:block;width:100%;">

<h:commandButton action="#{uploadPageBean.nextPage}"

image="images/continue.png"/>

</h:panelGroup>

</h:panelGrid>

</comp:fileUpload>

 

文件上传组件的value属性需要用一个拥有一个FileItem的属性绑定到一个bean上。组件只有在该文件被服务器成功收到时才显示。
三、 实现AJAX文件上传组件

实质上,上载组件或者生成一个完整的自已,或者在一个AJAX请求的情况下,只生成部分XML以更新在页面上进度条的状态。为了防止JavaServer Faces生成完整的组件树(这会带来不必要的负荷),我们还需要实现一个PhaseListener(PagePhaseListener)以取消该faces的请求处理的其它部分-如果遇到一个AJAX请求的话。我在本文中略去了所有的关于标准配置(faces-config.xml和标签库)的讨论,因为它们相当直接且已经在以前讨论过;而且这一切都包含在随同本文的源码中,你可以详细分析。

(一) AJAX文件上传组件生成器

该组件和标签类的实现比较简单。大量的逻辑被包含到生成器中,具体地说,它负责以下:

• 编码整个的上传组件(和完整的HTML文件上传标签)、文件被上传完成后要显示的组件,还有实现AJAX请求的客户端JavaScript代码。

• 适当地处理部分AJAX请求并且发送回必要的XML。

• 解码一个文件上传并且把它设置为一个FileItem实例。

(二) 编码整个上传组件

前面已经提及,文件上传组件由三个阶段组成。在该组件的整个编码期间,我们将详细分析这三个阶段的编码。注意,在页面上的该组件的可视化(使用CSS显示)属性将由AJAX JavaScript来控制。

(三) 阶段一

图5显示了该上传组件的第一个阶段。

图5.选择文件上传

在第一阶段中,我们需要生成HTML文件Upload标签和点击Upload按钮时相应的执行代码。一旦用户点击了Upload按钮,表单将被一个IFRAME(为防止页面阻塞)提交并初始化第二个阶段。下面是生成代码的一部分:

//文件上传组件

writer.startElement("input", component);

writer.writeAttribute("type", "file", null);

writer.writeAttribute("name", component.getClientId(context), "id");

writer.writeAttribute("id", component.getClientId(context),"id");

if(input.getValue() != null){

 //如果可用,则生成该文件名.

 FileItem fileData = (FileItem)input.getValue();

 writer.writeAttribute("value", fileData.getName(), fileData.getName());

}

writer.endElement("input");

String iconURL = input.getUploadIcon();

//生成图像,并把JavaScript事件依附到其上.

writer.startElement("div", component);

writer.writeAttribute("style",

"display:block;width:100%;text-align:center;", "style");

writer.startElement("img", component);

writer.writeAttribute("src",iconURL,"src");

writer.writeAttribute("type","image","type");

writer.writeAttribute("style","cursor:hand;cursor:pointer;","style");

UIForm form = FacesUtils.getForm(context,component);

if(form != null) {

 String getFormJS = "document.getElementById(

'" + form.getClientId(context) + "')";

 String jsFriendlyClientID = input.getClientId(context).replace(":","_");

 //设置表单的编码为multipart以用于文件上传,并且通过一个IFRAME

 //来提交它的内容。该组件的第二个阶段也在500毫秒后被初始化.

 writer.writeAttribute("onclick",

getFormJS + ".encoding='multipart/form-data';" +

getFormJS + ".target='" + iframeName + "';" + getFormJS + ".submit();" +

getFormJS + ".encoding='application/x-www-form-urlencoded';" +

getFormJS + ".target='_self';" +

"setTimeout('refreshProgress" + jsFriendlyClientID + "();',500);",null);

}

...

writer.endElement("img");

//现在实现我们将要把该文件/表单提交到的IFRAME.

writer.startElement("iframe", component);

writer.writeAttribute("id", iframeName, null);

writer.writeAttribute("name",iframeName,null);

writer.writeAttribute("style","display:none;",null);

writer.endElement("iframe");

writer.endElement("div");

writer.endElement("div"); //阶段1结束

TAG

Smile Big Smile Surprise Stick out tongue Wink Sad Tongue Tied Indifferent Crying Embarrassed Cool Angry Angel Devil [8-|] [:#] [:-*] [:^)] [<:o)] [|-)] Yes Beer Left Hug Music Star Time Snail Pizza Automobile Umbrella Computer Storm [mo] [8o|] [^o)] [+o(] [*-)] [8-)] Coffee No Drinks [Z] Right Hug Cake Broken Heart Gift Wilted Flower Movie Dog Idea Sleep Email Travel Paradise
呢称:

加粗 斜体 下划线 链接 图片 代码 邮件地址 引用 列表

最多只能输入100个字符