首页 - Ajax专区 - 实例应用

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

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

在UploadMultipartRequestWrapper类中,我们将初始化ServletFileUpload类,它负责分析我们的请求并且把文件写到服务器上的缺省临时目录。ServletFileUpload实例针对在该请求中遇到的每一个字段创建一个FileItem实例(它们包含文件上传和正常的表单元素)。之后,一个FileItem实例用于检索一个提交字段的属性,或者,在文件上传的情况下,检索一个到底层的临时文件的InputStream。总之,UploadMultipartRequestWrapper负责分析该文件并且设置任何FileItem-它在该请求中把文件上传描述为属性。然后,这些属性由JSF组件所进一步收集,而正常表单字段的行为保持不变。

默认情况下,通用FileUpload库将使用DiskFileItems类的实例来处理文件上传。尽管DiskFileItem在处理整个临时文件业务时是很有用的,但在准确监视该文件已经处理程度方面存在很少支持。自版本1.1以来,通用FileUpload库能够使开发者指定用于创建FileItem的工厂。我们将使用ProgressMonitorFileItemFactory和ProgressMonitorFileItem类来重载缺省行为并监视文件上传过程。
(三) 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();

}

 }

}

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个字符