Here we will see file upload example in jsf 2. The file upload implementation in Java based web application is very complex and we need to be dependent on Apache fileupload libraries. When we work on JSF(Java Server Faces), we have jsf pages with other inputs along with file inputs, so integration with Apache fileupload libraries make more complex or else we have to dependent on some third party file upload components like primefaces, richfaces etc.

Servlet 3.0 is part of Java EE 6 specification, hence “Part” interface and @MultiPartConfig annotation were introduced for easy way to do the file upload without any third party libraries. So any servlet 3.0 implementation servers like Tomcat 7.x, Jboss 6.x, GlassFish 3.x can get benefit of servlet 3.0 but the file upload feature is not available in JSF 2.1 and again we have to be dependent on servlet to do the file upload in JSF.
Recently JEE 7 specification was released and it’s now very easy to upload the file in JSF 2.2, because file upload component(<h:inputFile/>) was added in this version.

After completion of this example you will be able to see the output in the browser like following:

The home page

file upload example in jsf 2

When you click on the Upload button without selecting any file
file upload example in jsf

When a file is browsed and selected
file upload example in jsf 2

Finally when file gets uploaded
file upload example in jsf 2

We need to do the simple three steps for uploading file in JSF 2.2. Please find below steps to comple file upload example in jsf 2.

Add <h:inputFile> tag in JSF page
Add enctype=”multipart/form-data” attribute in enclosing <h:form> tag
Create the field in managed bean with “Part” data type.

Below example explains file upload function using <h:inputFile> tag    in JSF 2.2.

Prerequisites

JDK 1.6
Tomcat Server v7
javax.faces.jar

Files

Input Page: index.xhtml
Managed Bean: FileUploadMBean.java
Deployment descriptor: web.xml

Look at the below source codes:

Deployment descriptor – web.xml

Here in the below deployment descriptor file we have added context param to specify which environment we are working on.

We have also added the jsf servlet which works as a central servlet and handles all request and response for the clients.

We declared the welcome jsf page which is displayed when the application starts up.

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemalocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
    <display-name>jsf2-fileupload</display-name>
    <context-param>
        <param-name>javax.faces.PROJECT_STAGE</param-name>
        <param-value>Development</param-value>
    </context-param>
    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.jsf</url-pattern>
    </servlet-mapping>
    <welcome-file-list>
        <welcome-file>index.jsf</welcome-file>
    </welcome-file-list>
</web-app>

View – index.xhtml

This is the jsf page and it has two inputs for uploading two files. You can upload two files at a time or you can upload one file at a time.

Here notice we have used prependid=”false”, because we don’t want to append the form id with the input id or name. Suppose you have a form with id form1 and the form has input text field and input text field has id name then your input text field’s real id will be form1:name but it would be difficult to maintain such real id with javascript or java while we are trying to access directly. Using prependid=”false” gives us the real id as name of input text field.

<?xml version='1.0' encoding='UTF-8' ?>
<h:head>
<title>JSF 2.x File Upload Example</title>
</h:head>
<h:body>
    <h2>Select and upload a file</h2>
    <p>
        <!-- Shows the error or success message -->
        <h:outputtext value="#{fileUploadMBean.message}" rendered="#{!empty fileUploadMBean.message}"></h:outputtext>
        <!-- notice the enctype for file upload -->
        <h:form prependid="false" enctype="multipart/form-data">
            <h:panelgrid>
                <!-- input for files -->
                <h:inputfile value="#{fileUploadMBean.file1}"></h:inputfile>
                <h:inputfile value="#{fileUploadMBean.file2}"></h:inputfile>
                <!-- action which is responsible for uploading file(s) -->
                <h:commandbutton action="#{fileUploadMBean.uploadFile()}" value="Upload"></h:commandbutton>
            </h:panelgrid>
        </h:form>
    </p>
</h:body>

Managed Bean – FileUploadMBean.java

This is managed bean and it has an action called uploadFile() which gets triggered from the jsf page and uploads the file to the destination and you are in the right place for file upload example in jsf 2.

In this managed bean class we also bind the form’s input field to upload the files.

We also show the end users either success or error messages depending on the success or failure of file upload.

Notice we have kept the managed bean in view scope which is greater than request scope and less than session scope.

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.servlet.ServletContext;
import javax.servlet.http.Part;
@ManagedBean
@ViewScoped
public class FileUploadMBean implements Serializable {
    private static final long serialVersionUID = 1L;
    private Part file1;
    private Part file2;
    private String message;
    public Part getFile1() {
        return file1;
    }
    public void setFile1(Part file1) {
        this.file1 = file1;
    }
    public Part getFile2() {
        return file2;
    }
    public void setFile2(Part file2) {
        this.file2 = file2;
    }
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
    public String uploadFile() throws IOException {
        InputStream inputStream = null;
        OutputStream outputStream = null;
        FacesContext context = FacesContext.getCurrentInstance();
        ServletContext servletContext = (ServletContext) context
                .getExternalContext().getContext();
        String path = servletContext.getRealPath("");
        boolean file1Success = false;
        if (file1.getSize() &gt; 0) {
            String fileName = Utils.getFileNameFromPart(file1);
            /**
            * destination where the file will be uploaded
            */
            File outputFile = new File(path + File.separator + "WEB-INF"
                    + File.separator + fileName);
            inputStream = file1.getInputStream();
            outputStream = new FileOutputStream(outputFile);
            byte[] buffer = new byte[Constants.BUFFER_SIZE];
            int bytesRead = 0;
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }
            if (outputStream != null) {
                outputStream.close();
            }
            if (inputStream != null) {
                inputStream.close();
            }
            file1Success = true;
        }
        boolean file2Success = false;
        if (file2.getSize() &gt; 0) {
            String fileName = Utils.getFileNameFromPart(file2);
            File outputFile = new File(path + File.separator + "WEB-INF"
                    + File.separator + fileName);
            inputStream = file2.getInputStream();
            outputStream = new FileOutputStream(outputFile);
            byte[] buffer = new byte[Constants.BUFFER_SIZE];
            int bytesRead = 0;
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }
            if (outputStream != null) {
                outputStream.close();
            }
            if (inputStream != null) {
                inputStream.close();
            }
            file2Success = true;
        }
        if (file1Success || file2Success) {
            System.out.println("File uploaded to : " + path);
            /**
            * set the success message when the file upload is successful
            */
            setMessage("File successfully uploaded to " + path);
        } else {
            /**
            * set the error message when error occurs during the file upload
            */
            setMessage("Error, select atleast one file!");
        }
        /**
        * return to the same view
        */
        return null;
    }
}

Utils.java

This file contains all the utility methods used in application. For example, here we have only one method which extracts the file name from the “Part”.

import javax.servlet.http.Part;
public class Utils {
    public static String getFileNameFromPart(Part part) {
        final String partHeader = part.getHeader("content-disposition");
        for (String content : partHeader.split(";")) {
            if (content.trim().startsWith("filename")) {
                String fileName = content.substring(content.indexOf('=') + 1)
                        .trim().replace("\"", "");
                return fileName;
            }
        }
        return null;
    }
}

Constants.java

This file holds all the constants used in this application

public class Constants {
    private Constants() {
    }
    public static final int BUFFER_SIZE = 1024;
}

That’s all. Hope you have got idea how  on file upload example in jsf 2.

Thanks for reading.

Tags:

I am a professional Web developer, Enterprise Application developer, Software Engineer and Blogger. Connect me on Roy Tutorials | TwitterFacebook Google PlusLinkedin | Reddit

Leave a Reply

Your email address will not be published. Required fields are marked *