blob: 7e9a36a31ec2c2b0cc73a464d79d7b6669f8c0b0 [file] [log] [blame]
<?xml version="1.0"?>
<document>
<properties>
<title>Using FileUpload</title>
<author email="martinc@apache.org">Martin Cooper</author>
</properties>
<body>
<section name="Using FileUpload">
<p>
FileUpload can be used in a number of different ways, depending upon the
requirements of your application. In the simplest case, you will call a
single method to parse the servlet request, and then process the list of
items as they apply to your application. At the other end of the scale,
you might decide to customize FileUpload to take full control of the way
in which individual items are stored; for example, you might decide to
stream the content into a database.
</p>
<p>
Here, we will describe the basic principles of FileUpload, and illustrate
some of the simpler - and most common - usage patterns. Customization of
FileUpload is described <a href="customizing.html">elsewhere</a>.
</p>
</section>
<section name="How it works">
<p>
A file upload request comprises an ordered list of <em>items</em> that
are encoded according to
<a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a>,
"Form-based File Upload in HTML". FileUpload can parse such a request
and provide your application with a list of the individual uploaded
items. Each such item implements the <code>FileItem</code> interface,
regardless of its underlying implementation.
</p>
<p>
Each file item has a number of properties that might be of interest for
your application. For example, every item has a name and a content type,
and can provide an <code>InputStream</code> to access its data. On the
other hand, you may need to process items differently, depending upon
whether the item is a regular form field - that is, the data came from
an ordinary text box or similar HTML field - or an uploaded file. The
<code>FileItem</code> interface provides the methods to make such a
determination, and to access the data in the most appropriate manner.
</p>
<p>
FileUpload creates new file items using a <code>FileItemFactory</code>.
This is what gives FileUpload most of its flexibility. The factory has
ultimate control over how each item is created. The default factory
stores the item's data in memory or on disk, depending on the size of
the item (i.e. bytes of data). However, this behavior can be customized
to suit your application.
</p>
</section>
<section name="Parsing the request">
<p>
Before you can work with the uploaded items, of course, you need to parse
the request itself. Ensuring that the request is actually a file upload
request is straightforward, but FileUpload makes it simplicity itself, by
providing a static method to do just that.
</p>
<source><![CDATA[// Check that we have a file upload request
boolean isMultipart = FileUpload.isMultipartContent(request);]]></source>
<p>
Now we are ready to parse the request into its constituent items.
</p>
<subsection name="The simplest case">
<p>
The simplest usage scenario is the following:
<ul>
<li>
Uploaded items should be retained in memory as long as they are
reasonably small.
</li>
<li>
Larger items should be written to a temporary file on disk.
</li>
<li>
Very large upload requests should not be permitted.
</li>
<li>
The built-in defaults for the maximum size of an item to
be retained in memory, the maximum permitted size of an upload
request, and the location of temporary files are acceptable.
</li>
</ul>
</p>
<p>
Handling a request in this scenario couldn't be much simpler:
</p>
<source><![CDATA[// Create a new file upload handler
FileUpload upload = new DiskFileUpload();
// Parse the request
List /* FileItem */ items = upload.parseRequest(request);]]></source>
<p>
That's all that's needed. Really!
</p>
<p>
The result of the parse is a <code>List</code> of file items, each of
which implements the <code>FileItem</code> interface. Processing these
items is discussed below.
</p>
</subsection>
<subsection name="Exercising more control">
<p>
If your usage scenario is close to the simplest case, described above,
but you need a little more control over the size thresholds or the
location of temporary files, you can customize the behavior using the
methods of the <code>DiskFileUpload</code> class, like this:
</p>
<source><![CDATA[// Create a new file upload handler
DiskFileUpload upload = new DiskFileUpload();
// Set upload parameters
upload.setSizeThreshold(yourMaxMemorySize);
upload.setSizeMax(yourMaxRequestSize);
upload.setRepositoryPath(yourTempDirectory);
// Parse the request
List /* FileItem */ items = upload.parseRequest(request);]]></source>
<p>
Of course, each of the configuration methods is independent of the
others, but if you want to configure them all at once, you can do that
with an alternate <code>parseRequest()</code> method, like this:
</p>
<source><![CDATA[// Create a new file upload handler
DiskFileUpload upload = new DiskFileUpload();
// Parse the request
List /* FileItem */ items = upload.parseRequest(request,
yourMaxMemorySize, yourMaxRequestSize, yourTempDirectory);]]></source>
<p>
Should you need further control over the parsing of the request, such
as storing the items elsewhere - for example, in a database - you will
need to look into <a href="customizing.html">customizing</a> FileUpload.
</p>
</subsection>
</section>
<section name="Processing the uploaded items">
<p>
Once the parse has completed, you will have a <code>List</code> of file
items that you need to process. In most cases, you will want to handle
file uploads differently from regular form fields, so you might process
the list like this:
</p>
<source><![CDATA[// Process the uploaded items
Iterator iter = items.iterator();
while (iter.hasNext()) {
FileItem item = (FileItem) iter.next();
if (item.isFormField()) {
processFormField(item);
} else {
processUploadedFile(item);
}
}]]></source>
<p>
For a regular form field, you will most likely be interested only in the
name of the item, and its <code>String</code> value. As you might expect,
accessing these is very simple.
</p>
<source><![CDATA[// Process a regular form field
if (item.isFormField()) {
String name = item.getFieldName();
String value = item.getString();
...
}]]></source>
<p>
For a file upload, there are several different things you might want to
know before you process the content. Here is an example of some of the
methods you might be interested in.
</p>
<source><![CDATA[// Process a file upload
if (!item.isFormField()) {
String fieldName = item.getFieldName();
String fileName = item.getName();
String contentType = item.getContentType();
boolean isInMemory = item.isInMemory();
long sizeInBytes = item.getSize();
...
}]]></source>
<p>
With uploaded files, you generally will not want to access them via
memory, unless they are small, or unless you have no other alternative.
Rather, you will want to process the content as a stream, or write the
entire file to its ultimate location. FileUpload provides simple means of
accomplishing both of these.
</p>
<source><![CDATA[// Process a file upload
if (writeToFile) {
File uploadedFile = new File(...);
item.write(uploadedFile);
} else {
InputStream uploadedStream = item.getInputStream();
...
uploadedStream.close();
}]]></source>
<p>
Note that, in the default implementation of FileUpload, <code>write()</code>
will attempt to rename the file to the specified destination, if the data
is already in a temporary file. Actually copying the data is only done if
the the rename fails, for some reason, or if the data was in memory.
</p>
<p>
If you do need to access the uploaded data in memory, you need simply
call the <code>get()</code> method to obtain the data as an array of
bytes.
</p>
<source><![CDATA[// Process a file upload in memory
byte[] data = item.get();
...]]></source>
</section>
<section name="What's next">
<p>
Hopefully this page has provided you with a good idea of how to use
FileUpload in your own applications. For more detail on the methods
introduced here, as well as other available methods, you should refer
to the <a href="apidocs/index.html">JavaDocs</a>.
</p>
<p>
The usage described here should satisfy a large majority of file upload
needs. However, should you have more complex requirements, FileUpload
should still be able to help you, with it's flexible
<a href="customizing.html">customization</a> capabilities.
</p>
</section>
</body>
</document>