AJAX+JSF components achieve High-performance file uploads (3)

Source: Internet
Author: User
Tags filter file upload html form implement return tostring client

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.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.