Introduction

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 file upload libraries. When we work on JSF(Java Server Faces), we have jsf pages with other inputs along with file inputs on the web page, so integration with Apache file upload libraries make more complex or else we have to be 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.

Final Output

After completion of this example you will be able to see the output in the browser as shown below:

Home Page:

file upload example in jsf 2

When you click on 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 files get uploaded to the destination directory:

file upload example in jsf 2

File Upload Tag in JSF 2.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.8, Eclipse 4.9
Tomcat Server 8.5
JSF 2.2 API

Files Created in the Example

Input Page: index.xhtml
Managed Bean: FileUploadMBean.java, Utility Class: Utils.java
Deployment descriptor: web.xml

Example with Source Code

We will create web application with JSF 2.2 framework to upload files.

Creating Project

Create a maven based web project in Eclipse with below artifact and group id:

Group Id: com.jeejava, Artifact Id: jsf2-file-upload

Project Structure

The project structure in Eclipse looks like the below figure:

file upload example in jsf 2

Updating pom.xml

Make sure you have the following dependencies and plugin in your pom.xml file:

<project xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

	<modelVersion>4.0.0</modelVersion>

	<groupId>com.jeejava</groupId>
	<artifactId>jsf2-file-upload</artifactId>
	<packaging>war</packaging>
	<version>0.0.1-SNAPSHOT</version>

	<url>http://maven.apache.org</url>

	<dependencies>
		<dependency>
			<groupId>com.sun.faces</groupId>
			<artifactId>jsf-api</artifactId>
			<version>2.2.4</version>
		</dependency>
		<dependency>
			<groupId>com.sun.faces</groupId>
			<artifactId>jsf-impl</artifactId>
			<version>2.2.4</version>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>javax.servlet-api</artifactId>
			<version>3.1.0</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>javax.servlet.jsp</groupId>
			<artifactId>javax.servlet.jsp-api</artifactId>
			<version>2.3.1</version>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>jstl</artifactId>
			<version>1.1.2</version>
		</dependency>
	</dependencies>

	<build>
		<finalName>jsf2-file-upload</finalName>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.6.1</version>
				<configuration>
					<source>1.8</source>
					<target>1.8</target>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>

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.

We are using servlet 3.1 version, so accordingly we have declared the DTD version for our web app.

<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee 
		 http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
	version="3.1">
	<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>

Creating 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' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:h="http://xmlns.jcp.org/jsf/html"
	xmlns:f="http://xmlns.jcp.org/jsf/core"
	xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
	<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>
</html>

Creating JSF Managed Bean

In the below managed bean we have defined 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 and scope is available in the view only.

package com.jeejava.jsf.mbean;

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;

import com.jeejava.jsf.util.Utils;

@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() > 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[1024];
			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() > 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[1024];
			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;
	}
}

Utility Class – 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”.

package com.jeejava.jsf.util;

import javax.servlet.http.Part;

public class Utils {

	private 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;
	}

}

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

Source Code

You can download source code.

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 *