Upload files using Ajax and JSF Components

Source: Internet
Author: User
I. Introduction

Browser-based file upload, especially when the <input type = "file"> tag is included in the web page for upload, there are still serious performance problems. We know that uploading files larger than 10 MB often results in a very painful user experience. Once a user submits a file, the interface appears static when the browser uploads the file to the server. As all this happens in the background, many impatient users start to think that the server is "suspended" and submit files again, which of course makes the situation worse.

To make the file upload more friendly as possible, once the user submits the file, many sites will display an intermediate process animation (such as a rotating icon ). Although this technology plays a role in uploading and submitting to the server, it still provides too little information about the file upload status. Another attempt to solve this problem is to implement an applet, which uploads files to the server through FTP. The disadvantage of this solution is that it limits your users and requires a browser that supports Java.

In this article, we will implement an Ajax-capable component that not only uploads files to the server, but also "monitors the actual file upload process in real time. The four phases of this component work are shown in figure 1, 2, 3, and 4 below:


Figure 1. Phase 1: Select File Upload

Figure 2. Phase 2: Upload the file to the server

Figure 3. Phase 3: Upload complete

Figure 4. Phase 4: File Upload Summary

  Ii. implement this component

First, we analyze the process of creating multiple filters, which will allow us to process and monitor file uploads. Then, we will continue to implement the assumerver faces (JSF) component-it will provide continuous feedback to users to support Ajax progress bars.

(1) multi-part Filtering: uploadmultipartfilter

A multi-part filtering task intercepts the upload of an object and writes the object to a temporary directory on the server. It also monitors the number of bytes received and determines the extent to which the file has been uploaded. Fortunately, there is now an excellent Jakarta-commons open source library that can be used to analyze multiple HTTP requests and upload files to the server. What we need to do is expand the library and add the "Hook" we need to monitor how many bytes have been processed.

Public class uploadmultipartfilter implements filter {
Public void dofilter (servletrequest request, servletresponse response, filterchain chain)
Throws ioexception, servletexception {
Httpservletrequest hrequest = (httpservletrequest) request;
// Check whether we are processing a multi-part request
String contentheader = hrequest. getheader ("Content-Type ");
Boolean ismultipart = (contentheader! = NULL & contentheader. indexof ("multipart/form-Data ")! =-1 );
If (ismultipart = false ){
Chain. dofilter (request, response );
} Else {
Uploadmultipartrequestwrapper wrapper = new uploadmultipartrequestwrapper (hrequest );
Chain. dofilter (wrapper, response );
}
...
}

As you can see, the uploadmultipartfilter class simply checks whether the current request is a multi-part request. If the request does not contain file upload, the request will be passed to the next filter in the request chain without any additional processing. Otherwise, the request will be encapsulated in an uploadmultipartrequestwrapper.

(2) uploadmultipartrequestwrapper class

Public class uploadmultipartrequestwrapper
Extends httpservletrequestwrapper {
Private Map <string, string> formparameters;
Private Map <string, fileitem> fileparameters;
Public uploadmultipartrequestwrapper (httpservletrequest request ){
Super (request );
Try {
Servletfileupload upload = new servletfileupload ();
Upload. setfileitemfactory (New progressmonitorfileitemfactory (request ));
List fileitems = upload. parserequest (request );
Formparameters = new hashmap <string, string> ();
Fileparameters = new hashmap <string, fileitem> ();
For (INT I = 0; I <fileitems. Size (); I ++ ){
Fileitem item = (fileitem) fileitems. Get (I );
If (item. isformfield () = true ){
Formparameters. Put (item. getfieldname (), item. getstring ());
} Else {
Fileparameters. Put (item. getfieldname (), item );
Request. setattribute (item. getfieldname (), item );
}
}
} Catch (fileuploadexception Fe ){
// The request time exceeds-The user may have already transferred to another page.
// Make some records
//...
}
...

In the uploadmultipartrequestwrapper class, we will initialize the servletfileupload class, which analyzes our requests and writes the files to the default temporary directory on the server. The servletfileupload instance creates a fileitem instance (which contains file uploads and normal form elements) for each field encountered in the request ). Then, a fileitem instance is used to retrieve the attributes of a submitted field, or, when uploading a file, retrieves an inputstream of the underlying temporary file. In short, uploadmultipartrequestwrapper analyzes the file and sets any fileitem-it describes the file upload as a property in the request. These attributes are further collected by the JSF component, while the behavior of normal form fields remains unchanged.

By default, the general fileupload library uses the diskfileitems class instance to process file uploads. Although diskfileitem is useful in processing the entire temporary file business, it is rarely supported in accurately monitoring the degree of processing of the file. Since Version 1.1, the general fileupload library allows developers to specify the factory used to create fileitem. We will use the progressmonitorfileitemfactory and progressmonitorfileitem classes to overload the default behavior and monitor the File Upload process.

(3) progressmonitorfileitemfactory class

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) // This must be a file upload.
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 );
}
}
}
}

The progressmonitorfileitemfactory Content-Length header is set by the browser and is assumed to be the exact length of the Set Upload File. This method of determining the file length does limit the files you upload in each request-if multiple files are encoded in this request, this value is not accurate. This is because the browser only sends a Content-Length header, regardless of the number of uploaded files.

In addition to creating a progressmonitorfileitem instance, progressmonitorfileitemfactory also registers a progressobserver instance, which sends updates during File Upload by progressmonitorfileitem. Sessionupdatingprogressobserver sets the progress percentage to the user session for the ID of the submitted field. This value can then be accessed by the JSF component to send updates to users.

This article from http://90000cn.cn/Html/chengxusheji/Java/0233875407925.html
 

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.