Upload Files with JSF and MyFaces
The two filter parameters from the preceding
example tell MyFaces to keep files whose size is less that 100K in
memory and to ignore files that take more than 10MB of disk space. A
file whose size is between uploadThresholdSize and
uploadMaxFileSize is stored on disk as a temporary
file. If you try to upload a file that is too large, the current
version of MyFaces ignores all form data, as if the user submitted
an empty form. If you want to signal the failed upload to the user,
you would have to change the source code of the
MultipartRequestWrapper class of MyFaces. Look for the
place where the SizeLimitExceededException exception
is caught and use
FacesContext.getCurrentInstance().addMessage() to warn
the user.
As already mentioned, MyFaces Extensions contain a
file-uploading component that can be used in JSF pages. The next
section shows how to do this.
Using the File Upload Component of MyFaces
In order to use JSF and MyFaces in a web page, you have to
declare their tag libraries with the <%@taglib%>
directive:
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
<%@ taglib uri="http://myfaces.apache.org/extensions" prefix="x"%>
The <h:form> tag of JSF doesn't have a
method attribute, since it supports only the
POST method, but it has an enctype
attribute, which you must use if you want to upload files,
specifying the multipart encoding type for the form data:
<f:view>
<h:form id="MyForm" enctype="multipart/form-data" >
...
<x:inputFileUpload id="myFileId"
value="#{myBean.myFile}"
storage="file"
required="true"/>
...
</h:form>
</f:view>
The <x:inputFileUpload> tag of MyFaces lets
you define the attributes of the UI component whose renderer
produces the <input type="file"> element. The
org.apache.myfaces.custom.fileupload package contains
the UI component's class (HtmlInputFileUpload), its
renderer (HtmlFileUploadRenderer), the custom tag
handler (HtmlInputFileUploadTag), the
UploadedFile interface, and other helper classes. The
HtmlInputFileUpload class extends the standard
HtmlInputText component of JSF, overriding some of its
methods. The HtmlFileUploadRenderer is responsible for
generating the HTML markup and for getting the
FileItem from the
MultipartRequestWrapper.
Instead of giving you access to the FileItem
instance created by Commons File Upload, MyFaces provides its own
UploadedFile interface for getting the content of the
uploaded file, the content type, the file name, and its size. The
backing bean of your JSF form must have a property of the type
UploadedFile. The preceding example binds the value of
the UI component to such a bean property with a JSF expression
(#{myBean.myFile}). The JSF framework will get the
value of the HtmlInputFileUpload component, which is a
UploadedFile instance, and will set the
myFile property of the backing bean:
import org.apache.myfaces.custom.fileupload.UploadedFile;
...
public class MyBean {
private UploadedFile myFile;
public UploadedFile getMyFile() {
return myFile;
}
public void setMyFile(UploadedFile myFile) {
this.myFile = myFile;
}
...
}
It is important to know that MyFaces has two implementations of
its UploadedFile interface:
UploadedFileDefaultMemoryImpl and
UploadedFileDefaultFileImpl. The former is used when
the <x:inputFileUpload> tag doesn't have a
storage attribute or when the value of this attribute
is memory. The latter is used when the value of the
storage attribute is file.