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

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

[@more@]三、 实现AJAX文件上传组件

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

成都创新互联是专业的赵县网站建设公司,赵县接单;提供网站建设、成都网站制作,网页设计,网站设计,建网站,PHP网站建设等专业做网站服务;采用PHP框架,可快速的进行赵县网站开发网页制作和功能扩展;专业做搜索引擎喜爱的网站,专业的做网站团队,希望更多企业前来合作!

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

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

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

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

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

(二) 编码整个上传组件

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

(三) 阶段一

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

AJAX+JSF组件实现高性能的文件上载(3)498)this.style.width=498;" border="0" />

图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结束

(四) 阶段二

第二阶段是显示当前百分比的进度条和标签,如图6所示。该进度条是作为一个具有100个内嵌span标签的div标签实现的。这些将由AJAX JavaScript根据来自于服务器的响应进行设置。

AJAX+JSF组件实现高性能的文件上载(3)498)this.style.width=498;" border="0" />

图6.上传文件到服务器

writer.startElement("div",component);

writer.writeAttribute("id",
  input.getClientId(context) + "_stage2", "id");

...

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

String progressBarID = component.getClientId(context) + "_progressBar";

String progressBarLabelID =
  component.getClientId(context) + "_progressBarlabel";

writer.startElement("div", component);

writer.writeAttribute("id",progressBarID,"id");

String progressBarStyleClass = input.getProgressBarStyleClass();

if(progressBarStyleClass != null)

writer.writeAttribute("class",progressBarStyleClass,"class");

for(int i=0;i<100;i++){

 writer.write("<span> </span>");

}

writer.endElement("div");

writer.startElement("div",component);

writer.writeAttribute("id",progressBarLabelID,"id");

...

writer.endElement("div");

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

(五) 阶段三

最后,作为阶段三,一旦文件成功上传,需要被显示的组件即被生成,见图7。这些是在生成器的encodeChildren方法中实现的。

AJAX+JSF组件实现高性能的文件上载(3)498)this.style.width=498;" border="0" />

图7.上传完成

public void encodeChildren(FacesContext context,

UIComponent component) throws IOException {

 ResponseWriter writer = context.getResponseWriter();

 UIFileUpload input = (UIFileUpload)component;

 //一旦文件上传成功,处理将被显示的子结点

 writer.startElement("div", component);

 writer.writeAttribute("id", input.getClientId(context) + "_stage3", "id"); //阶段3.

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

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

 }else{

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

 }

 List<UIComponent> children = input.getChildren();

 for(UIComponent child : children){

FacesUtils.encodeRecursive(context,child);

 }

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

}

当前标题:AJAX+JSF组件实现高性能的文件上载(3)
浏览路径:http://azwzsj.com/article/gijgpi.html