ONJava.com -- The Independent Source for Enterprise Java
oreilly.comSafari Books Online.Conferences.


AddThis Social Bookmark Button

Upload Files with JSF and MyFaces

by 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 <input 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 path:

Web form containing a file input field
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 <form> tag. 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 POST method in the <form> tag:

<form enctype="multipart/form-data" method="POST" action="...">

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 files.

The org.apache.commons.fileupload package contains a class named DiskFileUpload whose parseRequest() method gets a HttpServletRequest parameter and returns a List of 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.


Next Pagearrow