Introduction
JavaServer Faces (JSF) is a superb web development framework as it abstract the handling of http requests and reponses. It makes the job of the developers easy by enabling the binding of html components to managed beans (java code with application logic).
However, uploading of files tend to be difficult due to the fact that JSF has no file upload component and or the capability of intelligently handle multipart/form-data requests. Therefore most of the developers (like me) would like to use JSF to upload files, hence we find it difficult. You and I only remain with three options
develop your own component
use a third-party components like Primefaces and MyFaces Tomahawk (does not work with JSF 2.0 as it uses facelets in the com.sun.faces.faclets package instead of javax.faces.facelets)
leave out anything to do with file upload.
In this article, I will show you how to create a custom file upload component. I will provide step by step guide and you will have your own component which can handle multiple file upload. The article has been divide in three consecutive parts (due to space limiting for content). I would have provided a zipped file but could not find a component for attaching zip files to the articles.
Requirements
To develop a custom file upload component you need the following libraries
JSF 2.0 (jsf-api.jar, jsf-impl.jar)
JSTL 1.2 (jstl-api.jar, jstl-impl.jar)
Common Fileupload (commons-fileupload-1.2.1.jar)
Common IO (commons-io-1.4.jar)
(The development and testing was done in tomcat 6.20 and servlet 2.5)
File Structure
The final structure of the site will be like this
demo
|----- files
|----- META-INF
|----- WEB-INF
|---- classes
|---- org
|---- idc
|---- bean
|---- Demo.java
|---- upload
|---- FileUpload.java
|---- UploadFilter.java
|---- UploadRenderer.java
|---- UploadTag.java
|---- FileValidator.java
|---- lib
|---- commons-fileupload-1.2.1.jar
|---- commons-io-1.4.jar
|---- jsf-api.jar
|---- jsf-impl.jar
|---- jstl-api.jar
|---- jstl-impl.jar
|---- faces-config.xml
|---- fileUpload-taglib.xml
|---- web.xml
|---- index.xhtml
The component we will develop will use <i:fileUpload id=yourID target=/files value=#{yourBean.uploadedFile /> and it will be rendered as <input type=file name=yourID id=yourID />
*Lets do the Work*
To create the project you can use any text editor, any IDE of your eg Eclipse, Netbeans etc.
I will use Eclipse Galileo to demonstrate how to create a fileUpload component. However you can use any IDE of your choice.
*Step 1*
Create a new Dynamic Web Project (in Eclipse)
Set the following dialogs as shown below
Project name = demo
Target Runtime =Apache Tomcat v6.0
Dynamic Web Module version = 2.5
Configuration= Default Configuration for Apache Tomcat v6.0
Click Next
Click Next again
Click Finish
*Step 2*
Create a package called org.idc.upload
Create a new class called UploadTag (within the org.idc.upload package). Copy the code below and paste it in your file
UploadTag.java
{code}/*
* @author Ben Mazyopa email: ben.mazyopa@cbu.ac.zm
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2009, Ben Mazyopa. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License
*
*/
package org.idc.upload;
import javax.el.ValueExpression;
import javax.faces.component.UIComponent;
import javax.faces.webapp.UIComponentELTag;
public class UploadTag extends UIComponentELTag {
private ValueExpression value;
private ValueExpression target;
public String getRendererType() { return "org.idc.upload.Upload"; }
public String getComponentType() { return "org.idc.upload.Upload"; }
public void setValue(ValueExpression newValue) { value = newValue; }
public void setTarget(ValueExpression newValue) { target = newValue; }
public void setProperties(UIComponent component) {
super.setProperties(component);
component.setValueExpression("target", target);
component.setValueExpression("value", value);
}
public void release() {
super.release();
value = null;
target = null;
}
}
This article continues below