Upload Files with JSF and MyFacesby Andrei Cioroianu
Web browsers provide an easy way for sending files to web applications, but the current versions of the Java web standards (servlets, JSP, and JSF) do not offer any help. Fortunately, there are third-party frameworks, such as Apache Commons File Upload, Apache MyFaces, and Oracle ADF Faces, that implement this feature, exposing simple APIs and custom tags. The first half of this article explains how file uploading works, walking you through the source code of MyFaces and Commons File Upload (the former uses the latter internally). It is helpful to know what happens inside of these open source frameworks in order to use them efficiently, and to be able to modify them if you have to. In the second half of the article, you'll find a sample application that lets users upload files using their web browsers.
Web-Based File Uploading
The term "upload" is somewhat overused. A webmaster would say that he uploads a file when he publishes it on his website. A web developer would say that he implements file uploading when he creates a HTML form and a script that lets regular users send files using their web browsers.
There is some overlapping between these two meanings, because a webmaster could use a web-based interface to publish files (pages, images, scripts, etc.). Companies that host personal web sites for free, such as Yahoo, implement web-based file uploading in order to let people upload their pages. This allows anyone with a web browser and internet access to publish a small website. However, there are much better ways for publishing your web content, such as FTP or secure FTP. In this case, you would use a dedicated application, such as a FTP client, instead of your web browser for uploading your content to the web server.
This article discusses file uploading from the web developer's point of view. For example, a web-based mail application, such as Yahoo mail, implements file uploading so that users can send messages with attachments. Another good example is a job website that lets you send your resume to technical recruiters. The example application of this article computes hash values of the uploaded files. You can do anything you want with the uploaded files in your own applications, such as storing their content into a database or mailing them as attachments. Now, let's see how to implement file uploading in a web application.
An HTML form can contain one or more
type="file"> elements that the browser renders as input
fields, where users are allowed to enter file paths. Next to each
file input field, the web browser adds a button that opens a file
dialog, letting users select a file instead of entering the
Figure 1. Web form containing a file input field
When the user clicks the form's Submit button, the web browser
encodes the form data, which includes the content of the selected
file along with its name (or path) and the other parameters of the
form. Then, the browser sends the encoded form data to the web
server, which passes this data to the script specified as the
action attribute of the
If you develop a Java web application, the action script can be a
servlet or a JSP page.
Because the default encoding of the form data and the default
GET method are not suitable for file uploading, a form
that contains file input fields must specify the
multipart/form-data encoding and the
method in the
<form enctype="multipart/form-data" method="POST" action="..."> ... <input type="file" name="..."> ... </form>
Things aren't as simple as they seem, however, because
application servers implementing the servlet and JSP
specifications are not required to handle the
multipart/form-data encoding. Therefore, you need a
parser for the request's input stream, such as Apache Commons File
Upload, which is a small Java package that lets you obtain the
content of the uploaded file from the encoded form data. The API of
this package is flexible, allowing you to keep small files in
memory while large files are stored on disk in a temporary
directory. You can specify the size threshold beyond which files
are written to disk instead of being kept in memory, and you can
also specify the maximum size that is allowed for the uploaded
org.apache.commons.fileupload package contains
a class named
parseRequest() method gets a
HttpServletRequest parameter and returns a
org.apache.commons.fileupload.FileItem instances. The
encoded form data is read from the stream returned by the
getInputStream() method of the servlet request. The
FileItem name is somewhat misleading, because the
instances of this interface represent both uploaded files and
regular request parameters.