ajax|js| Performance
Iv. Handling AJAX requests
The generation of AJAX requests is handled in the decoding method of this component. We need to check if this is an actual Ajax request (in order to distinguish it from normal compilation behavior), An XML response is then sent back to the client based on the value set in the session by the Sessionupdatingprogressobserver instance of the Progressmonitorfileitemfactory class.
public void decode (Facescontext context, uicomponent component) { Uifileupload input = (uifileupload) component; Check if this is an upload progress request, or an actual upload request. Externalcontext Extcontext = Context.getexternalcontext (); Map Parametermap = Extcontext.getrequestparametermap (); String clientId = Input.getclientid (context); Map Requestmap = Extcontext.getrequestparametermap (); if (Requestmap.get (clientId) = = null) { return;//do nothing, return } if (Parametermap.containskey (Progress_request_param_name)) { This is a request for progress information in the file request. Get the progress information and make it into XML HttpServletResponse response = (httpservletresponse) context.getexternalcontext (). GetResponse (); Set header information for a response Response.setcontenttype ("Text/xml"); Response.setheader ("Cache-control", "No-cache"); try { Responsewriter writer = Facesutils.setupresponsewriter (context); Writer.startelement ("Progress", input); Writer.startelement ("percentage", input); Gets the current percentage of progress from the session (set by the filter). Double progresscount = (double) extcontext.getsessionmap (). Get ("fileupload.progress." +input.getclientid); if (Progresscount!= null) { Writer.writetext (Progresscount, NULL); }else{ Writer.writetext ("1", null);/We haven't received the upload yet. } Writer.endelement ("percentage"); Writer.startelement ("clientId", input); Writer.writetext (Input.getclientid (context), NULL); Writer.endelement ("ClientId"); Writer.endelement ("Progress"); catch (Exception e) { Make some error records ... } }else{ A normal decoding request. ... |
v. Normal decoding behavior
During normal compilation, the file upload generator retrieves fileitem from the request attribute, where it is set by the filter and updates the component's value bindings. The progress in the session is then updated to 100%, so that JavaScript on the page can put the component into phase 3rd.
A normal decoding request. 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); Now we need to clear any progress associated with this item Extcontext.getsessionmap ("fileupload.progress." + input.getclientid (context), new Double (100)); }catch (Exception e) { throw new RuntimeException ("Cannot process file upload" + "-Please configure filter.", e); } } |
Client JavaScript is responsible for making progress requests to the server and moving components through different stages. To simplify the problem of handling all browser-specific XMLHttpRequest objects, I chose the Ajaxrequest.js library provided by Matt Krause. The library minimizes the number of JavaScript code that we need to write, and can make this component work properly. Perhaps it would be better to package this part of the JavaScript code as part of the component and then build it from Phaselistener, but I've tried to make it simple by defining a link to the JavaScript Library on the JSP page.
The Getprogressbarjavascript method in the component is called to generate JavaScript. Making JavaScript work normally is the hardest part of implementing AJAX components, but I think the following code is very clear and easy to understand. Although JavaScript is embedded in Java code in my example, it might be better to put it in an externally independent file. In this article, I just want to make the problem simpler and care only about the topic of this article. The following is an example of a JavaScript that will be generated by a component. This assumes that FILEUPLOAD1 is the JSF ID of the client being assigned to the file component, and Uploadform is the ID of the HTML form.
function refreshprogress () { Suppose we are entering into Phase 2. document.getElementById (' Fileupload1_stage1 '). style.display = ' None '; document.getElementById (' Fileupload1_stage2 '). style.display = '; document.getElementById (' Fileupload1_stage3 '). style.display = ' None '; Create Ajax Send Ajaxrequest.post ( { Specify the correct parameters so that The component is handled correctly on the server side ' Parameters ': {' uploadform ': ' Uploadform ', ' FileUpload1 ': ' FileUpload1 ', ' Jsf.component.UIFileUpload ': ' 1 ', ' Ajax.abortphase ': ' 4 '}//abort at Phase 4. Specifies that the appropriate callback method is successfully processed. , ' 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 '; Get percent from XML var percentage = xml.getelementsbytagname (' percentage ') [0].firstchild.nodevalue; var Innerspans = document.getElementById (clientId). getElementsByTagName (' span '); document.getElementById (clientId + ' label '). InnerHTML = Math.Round (percentage) + '% '; Sets the style classes for these spans based on the current progress. for (Var i=0;i<innerspans.length;i++) { if (I percentage) { Innerspans[i].classname = ' active '; }else{ Innerspans[i].classname = ' passive '; } } If the progress is not 100, we need to continue querying the server to implement the update. if (percentage!= 100) { SetTimeout (' refreshprogress () ', 400); } else { The file upload is complete and we now need to get the component into phase 3rd. document.getElementById (' Fileupload1_stage1 '). style.display = ' None '; document.getElementById (' Fileupload1_stage2 '). style.display = ' None '; document.getElementById (' Fileupload1_stage3 '). style.display = '; } } }); } return builder.tostring (); |
Vi. Conclusion
I am hopeful that this article will give you further thought about how to make file uploads more user-friendly and the possibility of using Ajax and JavaServer faces to implement advanced user interface components. There is no doubt that the scenarios in this article are lengthy and likely to be further improved. I would like you to give a detailed analysis of the complete source code provided in this article to get a thorough understanding of the concepts discussed in this article.