Apache Commons FileUpload

Source: Internet
Author: User
Tags rfc stream api

1 overview

The Commons fileupdate package makes it easy to add robust, high-performance file uploads to your servlet and Web applications.
FileUpload parsing follows the HTTP request in RFC 1876 (form-based file upload in HTML). That is, if an HTTP request is submitted using the Post method, and
and use the content type "Multipart/form-data", and then FileUpload parse the request, making the result easier for callers to use.
Starting with 1.3, FileUpload processes RFC 2047 encoded header values.

2 User Guide2.1 Using FileUpload

FileUpload can be used in a number of different ways, depending on the needs of your application. In a simple case, you will invoke a simple method to parse the servlet request,
Then process the item list as they apply to your application. At the other end of the balance, you may decide to customize the FileUpload Full control of a single item store
, for example, you might decide to write the contents of the stream to the database.
Here, we will describe the basic principles of fileupload and illustrate some of the simpler-and more general-usage patterns.
The FileUpload relies on Commons IO.

2.2 Working principle

A file upload request contains an ordered item list encoded according to RFC 1867 (form-based file uploads in HTML). FileUpload can parse such a request and provide a separate upload item list to your application. Each item implements the Fileitem interface, regardless of its underlying implementation.
This document describes the traditional API for the Commons FileUpload class library. Traditional APIs are a convenient way. However, for ultimate performance, you might prefer a fast streaming API.
Each file item has many properties that your application may be interested in. For example, each item has a name and content type, and provides a inputstream access
It's data. In other words, you might need to deal with different item, depending on whether the item is a regular form-that is, the data comes from the original text box or resembles an HTML field-or uploads a file. The Fileitem interface provides a way to make this decision and access the data in the most appropriate way.
FileUpload use Fileitemfactory to create a new file item. This gives fileupload greater flexibility. The factory ultimately controls how each item is created. Factory Real
The current transition FileUpload stores the item's data in memory or on disk, depending on the size of the item (for example, bytes of data). However, this behavior can be customized to suit your application.

2.3 Servlets and Portlets

Starting with 1.1, FileUpload supports file upload requests for servlet and portlet environments. The use is almost the same in both environments, so this article only covers
servlet environment.
If you build a portlet application, the following two points are different you should read the API documentation:

Servletfileupload class->portletfileupload Class
HttpServletRequest class->actionrequest Class

2.4 Parsing requests

Before you deal with uploading the item, of course, you need to parse the request. Make sure that the request is a simple real file upload request, but FileUpload makes it simple,
Do this by providing a static method.

Check that we have a file upload request
Boolean ismultipart = servletfileupload.ismultipartcontent (request);

Now we are ready to parse the request as item.

2.5 The simplest case

The following are the simplest use scenarios:

    • The upload item should remain in the content as long as it is quite small.

    • Large item should be written to a temporary file on disk.

    • Very large upload requests should not be allowed.

    • The built-in default maximum size of an item saved in memory, the maximum size of an upload request, and an acceptable temporary file location.

In this case, processing the request should not be simpler:

Create a factory based on the disk file item
Diskfileitemfactory factory = new Diskfileitemfactory ();

Configure a warehouse (to ensure a secure temporary location is used)
ServletContext ServletContext = This.getservletconfig (). Getservletcontext ();
File repository = (file) servletcontext.getattribute ("Javax.servlet.context.tempdir");
Factory.setrepository (repository);

Create a new file upload processor
Servletfileupload upload = new Servletfileupload (factory);

Parsing requests
list<fileitem> items = upload.parserequest (request);

This is all we need.
The result of parsing is the implementation of the file item List, each Fileitem interface.

2.6 Exercise more control

If you are using a scenario that is the simplest described above, but you need a little more control, you can easily customize the behavior of uploading the processor or file to the item factory.
The following examples show various configuration options:

Create a factory based on the disk file item
Diskfileitemfactory factory = new Diskfileitemfactory ();

Set up factory constraints
Factory.setsizethreshold (yourmaxmemorysize);
Factory.setrepository (yourtempdirectory);

Create a new file upload processor
Servletfileupload upload = new Servletfileupload (factory);

Set all request size constraints
Upload.setsizemax (yourmaxrequestsize);

Parsing requests
list<fileitem> items = upload.parserequest (request);

Of course, each configuration method is independent of other methods, but if you want to configure the factory at the same time, you can use constructors like this:

Create a disk-based text item factory
Diskfileitemfactory factory = new Diskfileitemfactory (yourmaxmemorysize, yourtempdirectory);

You should need more advanced controls on request resolution, such as storing item--elsewhere, for example, in a database.

2.7 Handling Upload Item

Once the parsing is complete, you will have a file that needs to be processed item List. In most cases, you will want to handle file uploads that are different from normal form fields.
So you can handle it like this:

Handling Upload Item
Iterator<fileitem> iter = Items.iterator ();
while (Iter.hasnext ()) {
Fileitem item = Iter.next ();

if (Item.isformfield ()) {
Processformfield (item);
} else {
Processuploadedfile (item);
}
}

For form fields, you will only be interested in the item name and its string value. As you would expect, access to these is very simple.

Working with regular form fields
if (Item.isformfield ()) {
String name = Item.getfieldname ();
String value = item.getstring ();
...
}

For file uploads, there are several different things that you might want to know before you deal with the content. Here are some examples of methods you might be interested in.

Handling file Uploads
if (!item.isformfield ()) {
String fieldName = Item.getfieldname ();
String fileName = Item.getname ();
String ContentType = Item.getcontenttype ();
Boolean isinmemory = Item.isinmemory ();
Long sizeinbytes = Item.getsize ();
...
}

With uploading files, you usually don't want to access them through memory unless they are small, or you have no other choice. You would rather have the content you want to handle as a stream, or write the entire file to its final location. FileUpload provides an easy way to accomplish both of these.

Handling file Uploads
if (WriteToFile) {
File UploadedFile = new file (...);
Item.write (UploadedFile);
} else {
InputStream Uploadedstream = Item.getinputstream ();
...
Uploadedstream.close ();
}

Note that in the default FileUpload implementation, if the data is already in a temporary file, write () will attempt to rename the file to the specified destination.
If you need to access the in-memory upload data, you need to simply call the Get () method to get the data as a byte array.

Handling in-memory file uploads
byte[] data = Item.get ();
...

2.8 Resource Cleanup

If you use Diskfileitem, the file you upload is processed before the temporary file is written. These temporary files are automatically deleted if they are no longer used if the corresponding Java.io.File instances are garbage collected. Silently opens a cleanup thread through the Org.apache.commons.io.FileCleaner class. This cleanup thread should be stopped if it is no longer needed. In a servlet environment, this is done by using a specific servlet context listener (filecleanercleanup). To do this, add the following in your Web. xml:

<web-app>
...
<listener>
<listener-class>
Org.apache.commons.fileupload.servlet.FileCleanerCleanup
</listener-class>
</listener>
...
</web-app>

2.9 Creating Diskfileitemfactory

Filecleanercleanup provides a org.apache.commons.io.FileCleaningTracker instance. This instance must be used when creating org.apache.commons.fileupload.disk.DiskFileItemFactory.

public static Diskfileitemfactory Newdiskfileitemfactory (ServletContext context, File repository) {
Filecleaningtracker Filecleaningtracker = filecleanercleanup.getfilecleaningtracker (context);
Diskfileitemfactory factory = new Diskfileitemfactory (Diskfileitemfactory.default_size_threshold, repository);
Factory.setfilecleaningtracker (Filecleaningtracker);
return factory;
}

2.10 Disabling temporary file cleanup

In order to disable temporary file tracing, you can set Filecleaningtracker to null. Therefore, the created file is no longer tracked. In particular, they will no longer be automatically deleted.

2.11 Integrated Virus Scanning

Virus scanning and web containers running on the same system can cause some unexpected behavior for applications that use FileUpload. This article describes some of the behaviors that you might encounter and provides some ways to handle them.
The default implementation of FileUpload will cause the uploaded item to be written to disk over a threshold value. For such a file to close, any virus scanner on the system will check it and possibly isolate the file-that is, move it to a place where the file cannot be caused. Of course, this will be a surprise to the application developer because uploading the file item is no longer valid. In other words, the upload item will be stored in the content under the same threshold, so it will not be detected by the virus scanner. This allows a virus to be retained in some form (although never written to disk, the virus scanner should locate and check it).
A common workaround is to place all uploaded files in one directory of the system and configure the virus scanner to ignore the directory. This will ensure that the application does not lose the file, but the virus scanner's scope of responsibility, virus scanning of uploaded files can be processed externally, moved cleanly or cleaned up files to "approved" locations, or integrated with virus scanners in the application.

2.12 Viewing processes

If you expect real large files to be uploaded, then it will be well reported to your users how much they have received. Each HTML page allows a progress bar to be implemented by returning a multipart/replace response or something like that.

Viewing upload progress can be done by providing a progress listener:

//Create a Progress listener
Progresslistener Progresslistener = new Progresslistener () {
   public void update (long Pbytesread, long pcontentlength, int pitems) {
       System.out.println ("We are Currently reading item "+ Pitems);
       if (pcontentlength = =-1) {
            System.out.println ("So far," + Pbytesread + "bytes has been read.");
      } else {
           System.out.println ("So far," + Pbytesread + "of" + pcontentlength
                                + "bytes has been read.");
      }
  }
};
Upload.setprogresslistener (progresslistener);

Do yourself a favor by implementing your first progress listener, like above, because it shows a trap: the progress listener is frequently called. Depending on the servlet engine and other environment factories, it may call any network package! In other words, your process listener can become a performance problem! A typical workaround is to reduce the activity of the progress listener. For example, you can send a message only when the number of megabytes changes:

Create a Progress listener
Progresslistener Progresslistener = new Progresslistener () {
Private long megabytes =-1;
public void update (long pbytesread, long pcontentlength, int pitems) {
Long mBytes = pbytesread/1000000;
if (megabytes = = MBytes) {
Return
}
megabytes = MBytes;
System.out.println ("We are currently reading item" + Pitems);
if (pcontentlength = =-1) {
System.out.println ("So far," + Pbytesread + "bytes has been read.");
} else {
System.out.println ("So far," + Pbytesread + "of" + pcontentlength
+ "bytes has been read.");
}
}
};

3 Stream API3.1 Why use a stream?

It is assumed that the file item must be stored in a certain place before it is actually accessed by the user. This is convenient because it allows easy access to the item content. In the words of saying,
It consumes memory and time.
The streaming API allows you to sacrifice a little convenience, optimize performance and lower memory configurations. However, the streaming API is more lightweight and therefore easy to understand.

3.2 Working principle

The FileUpload class is used to Access form fields and field orders, which have been sent through the client. However, Fileitemfactory is completely ignored.

3.3 Parsing requests

First, don't forget to make sure that the request is actually a file upload request. This is usually done by using the same static method.

Check that we have a file upload request
Boolean ismultipart = servletfileupload.ismultipartcontent (request);

Now we are ready to parse the request:

//Create new File upload processor
Servletfileupload upload = new Servletfileupload ();

//Parse request
Fileitemiterator iter = upload.getitemiterator (request);
while (Iter.hasnext ()) {
    fileitemstream item = Iter.next ();
    String name = Item.getfieldname ();
    InputStream stream = Item.openstream ();
    if (Item.isformfield ()) {
        System.out.println ( "Form Field" + Name + "with value"
            + streams.ass Tring (Stream) + "detected.");
   } else {
        System.out.println ("File field" + Name + "With file name"
            + item.getname () + "detected.") ;
       //Process input stream
        ...
   }
}






Apache Commons FileUpload

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.