AJAX+JSF組件實(shí)現(xiàn)高性能的文件上載(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(). 公司主營業(yè)務(wù):網(wǎng)站設(shè)計(jì)、網(wǎng)站制作、移動(dòng)網(wǎng)站開發(fā)等業(yè)務(wù)。幫助企業(yè)客戶真正實(shí)現(xiàn)互聯(lián)網(wǎng)宣傳,提高企業(yè)的競(jìng)爭(zhēng)能力。創(chuàng)新互聯(lián)建站是一支青春激揚(yáng)、勤奮敬業(yè)、活力青春激揚(yáng)、勤奮敬業(yè)、活力澎湃、和諧高效的團(tuán)隊(duì)。公司秉承以“開放、自由、嚴(yán)謹(jǐn)、自律”為核心的企業(yè)文化,感謝他們對(duì)我們的高要求,感謝他們從不同領(lǐng)域給我們帶來的挑戰(zhàn),讓我們激情的團(tuán)隊(duì)有機(jī)會(huì)用頭腦與智慧不斷的給客戶帶來驚喜。創(chuàng)新互聯(lián)建站推出官渡免費(fèi)做網(wǎng)站回饋大家。 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頭由瀏覽器設(shè)置并且假定它是被設(shè)置的上傳文件的精確長(zhǎng)度。這種確定文件長(zhǎng)度的方法確實(shí)限制了你在每次請(qǐng)求中上傳的文件-如果有多個(gè)文件在該請(qǐng)求中被編碼的話,不過這個(gè)值是不精確的。這是由于,瀏覽器僅僅發(fā)送一個(gè)Content-Length頭,而不考慮上傳的文件數(shù)目。
除了創(chuàng)建ProgressMonitorFileItem實(shí)例之外,ProgressMonitorFileItemFactory還注冊(cè)了一個(gè)ProgressObserver實(shí)例,它將由ProgressMonitorFileItem來發(fā)送文件上傳過程中的更新。我們所使用的ProgressObserver的實(shí)現(xiàn)(SessionUpdatingProgressObserver)針對(duì)被提交字段的id把進(jìn)度百分?jǐn)?shù)設(shè)置到用戶的會(huì)話中。然后,這個(gè)值可以由JSF組件存取以便把更新發(fā)送給用戶。
(四) 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包裝到一個(gè)BytesCountingOutputStream中,這可以在每次讀取一定數(shù)目的字節(jié)后更新相關(guān)的ProgressObserver。
(五) 支持AJAX的JavaServer Faces(JSF)上傳組件
這個(gè)組件負(fù)責(zé)生成HTML文件上傳標(biāo)簽,顯示一個(gè)進(jìn)度條以監(jiān)視文件上傳,并且生成一旦文件上傳成功需要被顯示的組件。使用JavaServer Faces實(shí)現(xiàn)這個(gè)組件的一個(gè)主要優(yōu)點(diǎn)是,大多數(shù)復(fù)雜性被隱藏起來。開發(fā)人員只需要把組件標(biāo)簽添加到JSP,而后由組件負(fù)責(zé)所有的AJAX及相關(guān)的進(jìn)度條監(jiān)控細(xì)節(jié)問題。下面的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屬性需要用一個(gè)擁有一個(gè)FileItem的屬性綁定到一個(gè)bean上。組件只有在該文件被服務(wù)器成功收到時(shí)才顯示。
|
網(wǎng)站標(biāo)題:AJAX+JSF組件實(shí)現(xiàn)高性能的文件上載(2)
轉(zhuǎn)載來于:
http://weahome.cn/article/ieihos.html