AJAX+JSF组件实现高性能的文件上载(2)
[@more@]三) ProgressMonitorFileItemFactory类 
| public class ProgressMonitorFileItemFactory extends DiskFileItemFactory {
 private File temporaryDirectory;
 
 private HttpServletRequest requestRef;
 
 private long requestLength;
 
 public ProgressMonitorFileItemFactory(HttpServletRequest request) {
 
 super();
 
 temporaryDirectory = (File)request.getSession().
 
 公司主营业务:网站设计、网站制作、移动网站开发等业务。帮助企业客户真正实现互联网宣传,提高企业的竞争能力。创新互联建站是一支青春激扬、勤奋敬业、活力青春激扬、勤奋敬业、活力澎湃、和谐高效的团队。公司秉承以“开放、自由、严谨、自律”为核心的企业文化,感谢他们对我们的高要求,感谢他们从不同领域给我们带来的挑战,让我们激情的团队有机会用头脑与智慧不断的给客户带来惊喜。创新互联建站推出官渡免费做网站回馈大家。 getServletContext().getAttribute("javax.servlet.context.tempdir");
 requestRef = request;
 
 String contentLength = request.getHeader("content-length");
 
 if(contentLength != null){requestLength
 = Long.parseLong(contentLength.trim());}
 }
 
 public FileItem createItem(String fieldName,
 String contentType,boolean isFormField, String fileName) {
 SessionUpdatingProgressObserver observer = null;
 
 if(isFormField == false) //这必须是一文件上传.
 
 observer = new SessionUpdatingProgressObserver(fieldName,fileName);
 
 ProgressMonitorFileItem item = new ProgressMonitorFileItem(
 
 fieldName,contentType,isFormField,
 
 fileName,2048,temporaryDirectory,
 
 observer,requestLength);
 
 return item;
 
 }
 
 ...
 
 public class SessionUpdatingProgressObserver implements ProgressObserver {
 
 private String fieldName;
 
 private String fileName;
 
 ...
 
 public void setProgress(double progress) {
 
 if(request != null){
 
 request.getSession().setAttribute(
 "FileUpload.Progress."+fieldName,progress);
 request.getSession().setAttribute(
 "FileUpload.FileName."+fieldName,fileName);
 }
 
 }
 
 }
 
 }
 | 
ProgressMonitorFileItemFactory Content-Length头由浏览器设置并且假定它是被设置的上传文件的精确长度。这种确定文件长度的方法确实限制了你在每次请求中上传的文件-如果有多个文件在该请求中被编码的话,不过这个值是不精确的。这是由于,浏览器仅仅发送一个Content-Length头,而不考虑上传的文件数目。
除了创建ProgressMonitorFileItem实例之外,ProgressMonitorFileItemFactory还注册了一个ProgressObserver实例,它将由ProgressMonitorFileItem来发送文件上传过程中的更新。我们所使用的ProgressObserver的实现(SessionUpdatingProgressObserver)针对被提交字段的id把进度百分数设置到用户的会话中。然后,这个值可以由JSF组件存取以便把更新发送给用户。
(四) ProgressMonitorFileItem类
| public class ProgressMonitorFileItem extends DiskFileItem {
 private ProgressObserver observer;
 
 private long passedInFileSize;
 
 ...
 
 private boolean isFormField;
 
 ...
 
 @Override
 
 public OutputStream getOutputStream() throws IOException {
 
 OutputStream baseOutputStream = super.getOutputStream();
 
 if(isFormField == false){
 
 return new BytesCountingOutputStream(baseOutputStream);
 
 }else{return baseOutputStream;}
 
 }
 
 ...
 
 private class BytesCountingOutputStream extends OutputStream{
 
 private long previousProgressUpdate;
 
 private OutputStream base;
 
 public BytesCountingOutputStream(OutputStream ous){ base = ous; }
 
 ...
 
 private void fireProgressEvent(int b){
 
 bytesRead += b;
 
 ...
 
 double progress = (((double)(bytesRead)) / passedInFileSize);
 
 progress *= 100.0
 
 observer.setProgress();
 
 }
 
 }
 
 }
 | 
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 >
 
 <h:commandButton action="#{uploadPageBean.reset}"
 
 image="images/reset.png"/>
 
 </h:panelGroup>
 
 <h:panelGroup >
 
 <h:commandButton action="#{uploadPageBean.nextPage}"
 
 image="images/continue.png"/>
 
 </h:panelGroup>
 
 </h:panelGrid>
 
 </comp:fileUpload>
 文件上传组件的value属性需要用一个拥有一个FileItem的属性绑定到一个bean上。组件只有在该文件被服务器成功收到时才显示。
 | 
            
            
                                                            
                                                新闻名称:AJAX+JSF组件实现高性能的文件上载(2)                                                
                                                转载来源:
http://www.scyingshan.cn/article/ieihos.html