温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

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

发布时间:2020-08-07 01:39:37 来源:ITPUB博客 阅读:129 作者:lonlux2 栏目:编程语言

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上。组件只有在该文件被服务器成功收到时才显示。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI