747 lines
29 KiB
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 – 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 ™</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>,
|
|
"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 <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("javax.servlet.context.tempdir");
|
|
factory.setRepository(repository);
|
|
|
|
// Create a new file upload handler
|
|
ServletFileUpload upload = new ServletFileUpload(factory);
|
|
|
|
// Parse the request
|
|
List<FileItem> 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<FileItem> 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<FileItem> 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><web-app>
|
|
...
|
|
<listener>
|
|
<listener-class>
|
|
org.apache.commons.fileupload.servlet.FileCleanerCleanup
|
|
</listener-class>
|
|
</listener>
|
|
...
|
|
</web-app></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 "approved" 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("We are currently reading item " + pItems);
|
|
if (pContentLength == -1) {
|
|
System.out.println("So far, " + pBytesRead + " bytes have been read.");
|
|
} else {
|
|
System.out.println("So far, " + pBytesRead + " of " + pContentLength
|
|
+ " bytes have been read.");
|
|
}
|
|
}
|
|
};
|
|
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("We are currently reading item " + pItems);
|
|
if (pContentLength == -1) {
|
|
System.out.println("So far, " + pBytesRead + " bytes have been read.");
|
|
} else {
|
|
System.out.println("So far, " + pBytesRead + " of " + pContentLength
|
|
+ " bytes have been read.");
|
|
}
|
|
}
|
|
};</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 © 2002-2018
|
|
<a href="https://www.apache.org/">The Apache Software Foundation</a>.
|
|
All Rights Reserved.</p>
|
|
</div>
|
|
</body>
|
|
|
|
</html>
|