FAISP/libs/commons-fileupload-1.4-bin/site/using.html

747 lines
29 KiB
HTML

<!DOCTYPE html>
<!--
| Generated by Apache Maven Doxia at 24 December 2018
| Rendered using Apache Maven Fluido Skin 1.3.0
-->
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta charset="iso-8859-1" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="author" content="Martin Cooper" />
<meta name="Date-Revision-yyyymmdd" content="20181224" />
<meta http-equiv="Content-Language" content="en" />
<title>FileUpload &#x2013; Using FileUpload</title>
<link rel="stylesheet" href="./css/bootstrap.min.css" type="text/css" />
<link rel="stylesheet" href="./css/site.css" type="text/css" />
<link rel="stylesheet" href="./css/print.css" media="print" />
<script type="text/javascript" src="./js/jquery.min.js"></script>
<script type="text/javascript" src="./js/bootstrap.min.js"></script>
<script type="text/javascript" src="./js/prettify.min.js"></script>
<script type="text/javascript" src="./js/site.js"></script>
</head>
<body class="composite">
<a href="http://commons.apache.org/" id="bannerLeft" title="Apache Commons logo">
<img class="logo-left" src="./images/commons-logo.png" alt="Apache Commons logo"/>
</a>
<a href="index.html" id="bannerRight">
<img class="logo-right" src="images/logo.png" alt="Commons FileUpload"/>
</a>
<div class="clear"></div>
<div class="navbar">
<div class="navbar-inner">
<div class="container-fluid">
<a class="brand" href="http://commons.apache.org/proper/commons-fileupload/">Apache Commons FileUpload &trade;</a>
<ul class="nav">
<li id="publishDate">Last Published: 24 December 2018</li>
<li class="divider">|</li> <li id="projectVersion">Version: 1.4</li>
</ul>
<div class="pull-right"> <ul class="nav">
<li>
<a href="http://www.apachecon.com/" class="externalLink" title="ApacheCon">
ApacheCon</a>
</li>
<li>
<a href="http://www.apache.org" class="externalLink" title="Apache">
Apache</a>
</li>
<li>
<a href="../../" title="Commons">
Commons</a>
</li>
</ul>
</div>
</div>
</div>
</div>
<div class="container-fluid">
<table class="layout-table">
<tr>
<td class="sidebar">
<div class="well sidebar-nav">
<ul class="nav nav-list">
<li class="nav-header">Commons FileUpload</li>
<li class="none">
<a href="index.html" title="Overview">
Overview</a>
</li>
<li class="none active">
<a href="using.html" title="User guide">
User guide</a>
</li>
<li class="none">
<a href="streaming.html" title="Streaming API">
Streaming API</a>
</li>
<li class="none">
<a href="faq.html" title="FAQ">
FAQ</a>
</li>
<li class="none">
<a href="javadocs/api-release/index.html" title="Javadoc (Latest release)">
Javadoc (Latest release)</a>
</li>
<li class="none">
<a href="download_fileupload.cgi" title="Download">
Download</a>
</li>
<li class="none">
<a href="security-reports.html" title="Security Reports">
Security Reports</a>
</li>
<li class="none">
<a href="mail-lists.html" title="Mailing lists">
Mailing lists</a>
</li>
<li class="none">
<a href="issue-tracking.html" title="Issue Tracking">
Issue Tracking</a>
</li>
<li class="none">
<a href="team-list.html" title="Team">
Team</a>
</li>
<li class="none">
<a href="source-repository.html" title="Source repository">
Source repository</a>
</li>
</ul>
<ul class="nav nav-list">
<li class="nav-header"><i class="icon-info-sign"></i>Project Documentation</li>
<li class="collapsed">
<a href="project-info.html" title="Project Information">
Project Information</a>
</li>
<li class="collapsed">
<a href="project-reports.html" title="Project Reports">
Project Reports</a>
</li>
</ul>
<ul class="nav nav-list">
<li class="nav-header">Commons</li>
<li class="none">
<a href="../../" title="Home">
Home</a>
</li>
<li class="none">
<a href="http://www.apache.org/licenses/" class="externalLink" title="License">
License</a>
</li>
<li class="collapsed">
<a href="../../components.html" title="Components">
Components</a>
</li>
<li class="collapsed">
<a href="../../sandbox/index.html" title="Sandbox">
Sandbox</a>
</li>
<li class="collapsed">
<a href="../../dormant/index.html" title="Dormant">
Dormant</a>
</li>
</ul>
<ul class="nav nav-list">
<li class="nav-header">General Information</li>
<li class="none">
<a href="../../security.html" title="Security">
Security</a>
</li>
<li class="none">
<a href="../../volunteering.html" title="Volunteering">
Volunteering</a>
</li>
<li class="none">
<a href="../../patches.html" title="Contributing Patches">
Contributing Patches</a>
</li>
<li class="none">
<a href="../../building.html" title="Building Components">
Building Components</a>
</li>
<li class="none">
<a href="../../commons-parent-pom.html" title="Commons Parent Pom">
Commons Parent Pom</a>
</li>
<li class="none">
<a href="../../build-plugin/index.html" title="Commons Build Plugin">
Commons Build Plugin</a>
</li>
<li class="none">
<a href="../../releases/index.html" title="Releasing Components">
Releasing Components</a>
</li>
<li class="none">
<a href="http://wiki.apache.org/commons/FrontPage" class="externalLink" title="Wiki">
Wiki</a>
</li>
</ul>
<ul class="nav nav-list">
<li class="nav-header">ASF</li>
<li class="none">
<a href="http://www.apache.org/foundation/how-it-works.html" class="externalLink" title="How the ASF works">
How the ASF works</a>
</li>
<li class="none">
<a href="http://www.apache.org/foundation/getinvolved.html" class="externalLink" title="Get Involved">
Get Involved</a>
</li>
<li class="none">
<a href="http://www.apache.org/dev/" class="externalLink" title="Developer Resources">
Developer Resources</a>
</li>
<li class="none">
<a href="http://www.apache.org/foundation/policies/conduct.html" class="externalLink" title="Code of Conduct">
Code of Conduct</a>
</li>
<li class="none">
<a href="http://www.apache.org/foundation/sponsorship.html" class="externalLink" title="Sponsorship">
Sponsorship</a>
</li>
<li class="none">
<a href="http://www.apache.org/foundation/thanks.html" class="externalLink" title="Thanks">
Thanks</a>
</li>
</ul>
</div>
<div id="poweredBy">
<a href="http://www.apache.org/events/current-event.html" title="ApacheCon" class="builtBy">
<img class="builtBy" alt="ApacheCon" src="http://www.apache.org/events/current-event-125x125.png" />
</a>
<a href="http://maven.apache.org/" title="Maven" class="builtBy">
<img class="builtBy" alt="Maven" src="http://maven.apache.org/images/logos/maven-feather.png" />
</a>
</div>
</td>
<td class="content">
<div class="section">
<h2><a name="Using_FileUpload"></a>Using FileUpload</h2>
<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>
<p>
FileUpload depends on Commons IO, so make sure you have the version
mentioned on the <a href="dependencies.html">dependencies page</a> in
your classpath before continuing.
</p>
</div>
<div class="section">
<h2><a name="How_it_works"></a>How it works</h2>
<p>
A file upload request comprises an ordered list of <i>items</i> that
are encoded according to
<a class="externalLink" href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a>,
&quot;Form-based File Upload in HTML&quot;. FileUpload can parse such a request
and provide your application with a list of the individual uploaded
items. Each such item implements the <tt>FileItem</tt> interface,
regardless of its underlying implementation.
</p>
<p>
This page describes the traditional API of the commons fileupload
library. The traditional API is a convenient approach. However, for
ultimate performance, you might prefer the faster
<a href="streaming.html">Streaming API</a>.
</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 <tt>InputStream</tt> 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
<tt>FileItem</tt> 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 <tt>FileItemFactory</tt>.
This is what gives FileUpload most of its flexibility. The factory has
ultimate control over how each item is created. The factory implementation
that currently ships with FileUpload 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>
</div>
<div class="section">
<h2><a name="Servlets_and_Portlets"></a>Servlets and Portlets</h2>
<p>
Starting with version 1.1, FileUpload supports file upload requests in
both servlet and portlet environments. The usage is almost identical in
the two environments, so the remainder of this document refers only to
the servlet environment.
</p>
<p>
If you are building a portlet application, the following are the two
distinctions you should make as you read this document:</p>
<ul>
<li>
Where you see references to the <tt>ServletFileUpload</tt> class,
substitute the <tt>PortletFileUpload</tt> class.
</li>
<li>
Where you see references to the <tt>HttpServletRequest</tt> class,
substitute the <tt>ActionRequest</tt> class.
</li>
</ul>
</div>
<div class="section">
<h2><a name="Parsing_the_request"></a>Parsing the request</h2>
<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>
<div class="source">
<pre>// Check that we have a file upload request
boolean isMultipart = ServletFileUpload.isMultipartContent(request);</pre></div>
<p>
Now we are ready to parse the request into its constituent items.
</p>
<div class="section">
<h3><a name="The_simplest_case"></a>The simplest case</h3>
<p>The simplest usage scenario is the following:</p>
<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>
Handling a request in this scenario couldn't be much simpler:
</p>
<div class="source">
<pre>// Create a factory for disk-based file items
DiskFileItemFactory factory = new DiskFileItemFactory();
// Configure a repository (to ensure a secure temp location is used)
ServletContext servletContext = this.getServletConfig().getServletContext();
File repository = (File) servletContext.getAttribute(&quot;javax.servlet.context.tempdir&quot;);
factory.setRepository(repository);
// Create a new file upload handler
ServletFileUpload upload = new ServletFileUpload(factory);
// Parse the request
List&lt;FileItem&gt; items = upload.parseRequest(request);</pre></div>
<p>
That's all that's needed. Really!
</p>
<p>
The result of the parse is a <tt>List</tt> of file items, each of
which implements the <tt>FileItem</tt> interface. Processing these
items is discussed below.
</p>
</div>
<div class="section">
<h3><a name="Exercising_more_control"></a>Exercising more control</h3>
<p>
If your usage scenario is close to the simplest case, described above,
but you need a little more control, you can easily customize the
behavior of the upload handler or the file item factory or both. The
following example shows several configuration options:
</p>
<div class="source">
<pre>// Create a factory for disk-based file items
DiskFileItemFactory factory = new DiskFileItemFactory();
// Set factory constraints
factory.setSizeThreshold(yourMaxMemorySize);
factory.setRepository(yourTempDirectory);
// Create a new file upload handler
ServletFileUpload upload = new ServletFileUpload(factory);
// Set overall request size constraint
upload.setSizeMax(yourMaxRequestSize);
// Parse the request
List&lt;FileItem&gt; items = upload.parseRequest(request);</pre></div>
<p>
Of course, each of the configuration methods is independent of the
others, but if you want to configure the factory all at once, you can
do that with an alternative constructor, like this:
</p>
<div class="source">
<pre>// Create a factory for disk-based file items
DiskFileItemFactory factory = new DiskFileItemFactory(yourMaxMemorySize, yourTempDirectory);</pre></div>
<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>
</div>
</div>
<div class="section">
<h2><a name="Processing_the_uploaded_items"></a>Processing the uploaded items</h2>
<p>
Once the parse has completed, you will have a <tt>List</tt> 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>
<div class="source">
<pre>// Process the uploaded items
Iterator&lt;FileItem&gt; iter = items.iterator();
while (iter.hasNext()) {
FileItem item = iter.next();
if (item.isFormField()) {
processFormField(item);
} else {
processUploadedFile(item);
}
}</pre></div>
<p>
For a regular form field, you will most likely be interested only in the
name of the item, and its <tt>String</tt> value. As you might expect,
accessing these is very simple.
</p>
<div class="source">
<pre>// Process a regular form field
if (item.isFormField()) {
String name = item.getFieldName();
String value = item.getString();
...
}</pre></div>
<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>
<div class="source">
<pre>// 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();
...
}</pre></div>
<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>
<div class="source">
<pre>// Process a file upload
if (writeToFile) {
File uploadedFile = new File(...);
item.write(uploadedFile);
} else {
InputStream uploadedStream = item.getInputStream();
...
uploadedStream.close();
}</pre></div>
<p>
Note that, in the default implementation of FileUpload, <tt>write()</tt>
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 <tt>get()</tt> method to obtain the data as an array of
bytes.
</p>
<div class="source">
<pre>// Process a file upload in memory
byte[] data = item.get();
...</pre></div>
</div>
<div class="section">
<h2><a name="Resource_cleanup"></a>Resource cleanup</h2>
<p>
This section applies only, if you are using the
<a href="./apidocs/org/apache/commons/fileupload/disk/DiskFileItem.html">DiskFileItem</a>.
In other words, it applies, if your uploaded files are written to
temporary files before processing them.
</p>
<p>
Such temporary files are deleted automatically, if they are no longer
used (more precisely, if the corresponding instance of <tt>DiskFileItem</tt>
is garbage collected. This is done silently by the <tt>org.apache.commons.io.FileCleanerTracker</tt>
class, which starts a reaper thread.
</p>
<p>
This reaper thread should be stopped, if it is no longer needed. In
a servlet environment, this is done by using a special servlet
context listener, called
<a href="./apidocs/org/apache/commons/fileupload/servlet/FileCleanerCleanup.html">FileCleanerCleanup</a>.
To do so, add a section like the following to your <tt>web.xml</tt>:
</p>
<div class="source">
<pre>&lt;web-app&gt;
...
&lt;listener&gt;
&lt;listener-class&gt;
org.apache.commons.fileupload.servlet.FileCleanerCleanup
&lt;/listener-class&gt;
&lt;/listener&gt;
...
&lt;/web-app&gt;</pre></div>
<div class="section">
<h3><a name="Creating_a_DiskFileItemFactory"></a>Creating a DiskFileItemFactory</h3>
<p>
The FileCleanerCleanup provides an instance of
<tt>org.apache.commons.io.FileCleaningTracker</tt>. This
instance must be used when creating a
<tt>org.apache.commons.fileupload.disk.DiskFileItemFactory</tt>.
This should be done by calling a method like the following:
</p>
<div class="source">
<pre>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;
}</pre></div>
</div>
<div class="section">
<h3><a name="Disabling_cleanup_of_temporary_files"></a>Disabling cleanup of temporary files</h3>
<p>
To disable tracking of temporary files, you may set the
<tt>FileCleaningTracker</tt> to null. Consequently,
created files will no longer be tracked. In particular,
they will no longer be deleted automatically.</p>
</div>
</div>
<div class="section">
<h2><a name="Interaction_with_virus_scanners"></a>Interaction with virus scanners</h2>
<p>
Virus scanners running on the same system as the web container can cause
some unexpected behaviours for applications using FileUpload. This section
describes some of the behaviours that you might encounter, and provides
some ideas for how to handle them.
</p>
<p>
The default implementation of FileUpload will cause uploaded items above
a certain size threshold to be written to disk. As soon as such a file is
closed, any virus scanner on the system will wake up and inspect it, and
potentially quarantine the file - that is, move it to a special location
where it will not cause problems. This, of course, will be a surprise to
the application developer, since the uploaded file item will no longer be
available for processing. On the other hand, uploaded items below that
same threshold will be held in memory, and therefore will not be seen by
virus scanners. This allows for the possibility of a virus being retained
in some form (although if it is ever written to disk, the virus scanner
would locate and inspect it).
</p>
<p>
One commonly used solution is to set aside one directory on the system
into which all uploaded files will be placed, and to configure the virus
scanner to ignore that directory. This ensures that files will not be
ripped out from under the application, but then leaves responsibility for
virus scanning up to the application developer. Scanning the uploaded
files for viruses can then be performed by an external process, which
might move clean or cleaned files to an &quot;approved&quot; location, or by
integrating a virus scanner within the application itself. The details of
configuring an external process or integrating virus scanning into an
application are outside the scope of this document.
</p>
</div>
<div class="section">
<h2><a name="Watching_progress"></a>Watching progress</h2>
<p>
If you expect really large file uploads, then it would be nice to report
to your users, how much is already received. Even HTML pages allow to
implement a progress bar by returning a multipart/replace response,
or something like that.
</p>
<p>
Watching the upload progress may be done by supplying a progress listener:
</p>
<div class="source">
<pre>//Create a progress listener
ProgressListener progressListener = new ProgressListener(){
public void update(long pBytesRead, long pContentLength, int pItems) {
System.out.println(&quot;We are currently reading item &quot; + pItems);
if (pContentLength == -1) {
System.out.println(&quot;So far, &quot; + pBytesRead + &quot; bytes have been read.&quot;);
} else {
System.out.println(&quot;So far, &quot; + pBytesRead + &quot; of &quot; + pContentLength
+ &quot; bytes have been read.&quot;);
}
}
};
upload.setProgressListener(progressListener);</pre></div>
<p>
Do yourself a favour and implement your first progress listener just
like the above, because it shows you a pitfall: The progress listener
is called quite frequently. Depending on the servlet engine and other
environment factory, it may be called for any network packet! In
other words, your progress listener may become a performance problem!
A typical solution might be, to reduce the progress listeners activity.
For example, you might emit a message only, if the number of megabytes
has changed:
</p>
<div class="source">
<pre>//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(&quot;We are currently reading item &quot; + pItems);
if (pContentLength == -1) {
System.out.println(&quot;So far, &quot; + pBytesRead + &quot; bytes have been read.&quot;);
} else {
System.out.println(&quot;So far, &quot; + pBytesRead + &quot; of &quot; + pContentLength
+ &quot; bytes have been read.&quot;);
}
}
};</pre></div>
</div>
<div class="section">
<h2><a name="What.27s_next"></a>What's next</h2>
<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>
</div>
</td>
</tr>
</table>
</div>
<div class="footer">
<p>Copyright &copy; 2002-2018
<a href="https://www.apache.org/">The Apache Software Foundation</a>.
All Rights Reserved.</p>
</div>
</body>
</html>