You are on page 1of 3

JSF 2.2: File upload with h:inputFile | JSFlive: Mi... https://jsflive.wordpress.com/2013/04/23/jsf22-fil...

JSFlive: Michael Kurz's JSF Weblog


Random thoughts about JavaServer Faces and related stuff

JSF 2.2: File upload with h:inputFile


Posted on April 23, 2013 | 27 Comments

After so many years it finally happened! The JSF 2.2 specification features a file upload component. In this
post of the series on JSF 2.2 I will show how to upload files with the brand new h:inputFile component.

As JSF 2.2 requires Servlet 3.0 it is finally possible to have the file upload component h:inputFile in the
standard. h:inputFile is basically used like any other JSF input component. The upload is stored in a
bean property of type javax.servlet.http.Part referenced in the value attribute. As a prerequisite,
the form submit encoding must be set to multipart/form-data in the enctype attribute of the enclosing
h:form.

The following listing shows a form with a file upload component and a command button referencing an
action method which processes the uploaded file.

<h:form id="form" enctype="multipart/form-data">


<h:inputFile id="file" value="#{bean.file}"/>
<h:commandButton value="Upload"
action="#{bean.upload}"/>
</h:form>

The next listing shows the bean used in the view above. In the action method upload() the content of the
file is read from the provided input stream and stored in the String fileContent.

public class Bean {


private Part file;
private String fileContent;

public void upload() {


try {
fileContent = new Scanner(file.getInputStream())

1 of 9 1/23/19, 6:40 PM
JSF 2.2: File upload with h:inputFile | JSFlive: Mi... https://jsflive.wordpress.com/2013/04/23/jsf22-fil...

.useDelimiter("\\A").next();
} catch (IOException e) {
// Error handling
}
}

public Part getFile() {


return file;
}

public void setFile(Part file) {


this.file = file;
}
}

As h:inputFile is a JSF input component, it can have a converter and validators. Let’s add a validator to
the component that checks the size and mime type of the uploaded file. The validation is done in the
validator method validateFile in the managed bean. This method is referenced in the validator
attribute of h:inputFile like this:

<h:inputFile id="file" value="#{bean.file}"


validator="#{bean.validateFile}"/>

The following listing shows the validator method itself. You will see that there is nothing fancy about it.
The validation works just like it would for any other input component. As mentioned before, the uploaded
file is stored in an instance of class javax.servlet.http.Part. Therefore we can assume this class for
the object passed into the validator which allows us to check the size and content type.

public void validateFile(FacesContext ctx,


UIComponent comp,
Object value) {
List<FacesMessage> msgs = new ArrayList<FacesMessage>();
Part file = (Part)value;
if (file.getSize() > 1024) {
msgs.add(new FacesMessage("file too big"));
}
if (!"text/plain".equals(file.getContentType())) {
msgs.add(new FacesMessage("not a text file"));

2 of 9 1/23/19, 6:40 PM
JSF 2.2: File upload with h:inputFile | JSFlive: Mi... https://jsflive.wordpress.com/2013/04/23/jsf22-fil...

}
if (!msgs.isEmpty()) {
throw new ValidatorException(msgs);
}
}

JSF also specifies uploading files via Ajax. h:inputFile can be combined with f:ajax like any other JSF
input component. In the following listing the file upload is initiated via an ajaxified h:commandButton.
But it would also be possible to add f:ajax directly to h:inputFile. In this case the ajax request would
be started with the (pseudo) event valueChange.

<h:form id="form" enctype="multipart/form-data">


<h:inputFile id="file" value="#{bean.file}"
validator="#{bean.validateFile}"/>
<h:commandButton value="Upload"
action="#{bean.upload}">
<f:ajax execute="file" render="@all"/>
</h:commandButton>
<h:inputTextarea value="#{bean.fileContent}"
readonly="true"/>
</h:form>

Normally, render would contain the IDs of components to re-render. Unfortunately, Mojarra currently has
a bug that forces the use of @all for ajax requests with file uploads (see JAVASERVERFACES-2851 for
details).

The source code for the JSF 2.2 series examples can be found in the JSFlive Github repository jsf22-
examples (module jsf22-input-file).

Further official details about JSF 2.2 can be found in the JSR 344: JavaServer Faces 2.2.

3 of 9 1/23/19, 6:40 PM

You might also like