溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

AJAX+JSF組件實現高性能的文件上載(4)

發布時間:2020-08-14 17:16:56 來源:ITPUB博客 閱讀:162 作者:lonlux2 欄目:編程語言

AJAX+JSF組件實現高性能的文件上載(4)

[@more@]四、處理AJAX請求

AJAX請求的生成是在這個組件的解碼方法中處理的。我們需要檢查這是否是一個實際的AJAX請求(為了區別于正常的編譯行為),然后基于由ProgressMonitorFileItemFactory類的SessionUpdatingProgressObserver實例設置在會話中的值把一個XML響應發送回客戶端。

public void decode(FacesContext context, UIComponent component) {

 UIFileUpload input = (UIFileUpload) component;

 //檢查是否這是一個上傳進度請求,或是一個實際的上傳請求.

 ExternalContext extContext = context.getExternalContext();

 Map parameterMap = extContext.getRequestParameterMap();

 String clientId = input.getClientId(context);

 Map requestMap = extContext.getRequestParameterMap();

 if(requestMap.get(clientId) == null){

return;//什么也不做,返回

 }

 if(parameterMap.containsKey(PROGRESS_REQUEST_PARAM_NAME)){

//這是一個在該文件請求中的得到進度信息的請求.

//得到該進度信息并把它生成為XML

HttpServletResponse response =

(HttpServletResponse)context.getExternalContext().getResponse();

//設置響應的頭信息

response.setContentType("text/xml");

response.setHeader("Cache-Control", "no-cache");

try {

 ResponseWriter writer = FacesUtils.setupResponseWriter(context);

 writer.startElement("progress", input);

 writer.startElement("percentage", input);

 //從會話中獲得當前進度百分數(由過濾器所設置).

 Double progressCount = (Double)extContext.getSessionMap().

 get("FileUpload.Progress." +input.getClientId(context));

 if(progressCount != null){

writer.writeText(progressCount, null);

 }else{

writer.writeText("1", null);//我們還沒有收到上傳

 }

 writer.endElement("percentage");

 writer.startElement("clientId", input);

 writer.writeText(input.getClientId(context), null);

 writer.endElement("clientId");

 writer.endElement("progress");

} catch(Exception e){

 //做一些錯誤記錄...

}

}else{

 //正常的譯碼請求.

...

五、 正常的譯碼行為

在正常的編譯期間,文件上傳生成器從請求屬性中檢索FileItem,正是在此處它被過濾器所設置,并且更新該組件的值綁定。然后,該會話中的進度被更新到100%,這樣在頁面上的JavaScript就可以把組件送入第3個階段。

//正常的譯碼請求.

if(requestMap.get(clientId).toString().equals("file")){

try{

 HttpServletRequest request = (HttpServletRequest)extContext.getRequest();

 FileItem fileData = (FileItem)request.getAttribute(clientId);

 if(fileData != null) input.setSubmittedValue(fileData);

 //現在我們需要清除與該項相關的任何進度

 extContext.getSessionMap().put(

"FileUpload.Progress." + input.getClientId(context),new Double(100));

}catch(Exception e){

 throw new RuntimeException("不能處理文件上傳" +" - 請配置過濾器.",e);

}

}

客戶端JavaScript負責向服務器發出進度請求并通過不同階段來移動組件。為了簡化處理所有的瀏覽器特定的XMLHttpRequest對象的問題,我選用了Matt Krause提供的AjaxRequest.js庫。該庫最大限度地減少我們需要編寫的JavaScript代碼的數量,同時可以使這個組件正常工作。也許把這部分JavaScript代碼打包為該組件的一部分,然后從PhaseListener生成它更好一些,但是,我已經通過定義一個到JSP頁面上的JavaScript庫的鏈接來盡力使得它簡單。

組件中的getProgressBarJavaScript方法被調用以生成JavaScript。使JavaScript正常工作通常是實現AJAX組件最困難的部分;不過我想,下面的代碼已經非常清晰易于理解了。盡管在我的示例中JavaScript是嵌入到Java代碼中的,但是把它放到一個外部獨立的文件中也許更好一些。在本文中,我只是想使問題更為簡單些且只關心本文的主題。下面是一個將由組件生成的JavaScript的示例。其中假定,fileUpload1是被賦值到該文件組件的客戶端JSF Id,而uploadForm是HTML表單的Id。

function refreshProgress(){

 // 假定我們正在進入到階段2.

 document.getElementById('fileUpload1_stage1').style.display = 'none';

 document.getElementById('fileUpload1_stage2').style.display = '';

 document.getElementById('fileUpload1_stage3').style.display = 'none';

 //創建AJAX寄送

 AjaxRequest.post(

 {

//指定正確的參數,以便

//該組件在服務器端被正確處理

'parameters':{ 'uploadForm':'uploadForm',

'fileUpload1':'fileUpload1',

'jsf.component.UIFileUpload':'1',

'ajax.abortPhase':'4' } //Abort at Phase 4.

//指定成功處理相應的回調方法.

,'onSuccess':function(req) {

var xml = req.responseXML;

if( xml.getElementsByTagName('clientId').length == 0) {

 setTimeout('refreshProgress()',200); return;

}

var clientId = xml.getElementsByTagName('clientId');

clientId = clientId[0].firstChild.nodeValue + '_progressBar';

//從XML獲取百分比

var percentage =

xml.getElementsByTagName('percentage')[0].firstChild.nodeValue;

var innerSpans =

document.getElementById(clientId).getElementsByTagName('span');

document.getElementById(clientId + 'label').innerHTML

= Math.round(percentage) + '%';

//基于當前進度,設置這些span的式樣類。

for(var i=0;i<innerSpans.length;i++){

 if(i < percentage){

innerSpans[i].className = 'active';

 }else{

innerSpans[i].className = 'passive';

 }

}

//如果進度不是100,我們需要繼續查詢服務器以實現更新.

if(percentage != 100){

 setTimeout('refreshProgress()',400);

} else {

 //文件上傳已經完成,我們現在需要把該組件送入到第3個階段.

 document.getElementById('fileUpload1_stage1').style.display = 'none';

 document.getElementById('fileUpload1_stage2').style.display = 'none';

 document.getElementById('fileUpload1_stage3').style.display = '';

}

 }

});

}

return builder.toString();

六、 結論

我很希望,本文能夠在有關如何使得文件上傳更具有用戶友好性,并且把AJAX和JavaServer Faces用于實現高級用戶接口組件的可能性方面引發你的進一步思考。毫無疑問,本文中的方案比較冗長并且有可能得到進一步的改進。我希望你能詳細地分析一下本文中所提供的完整的源代碼來深入理解本文中所討論的概念。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女