AJAX File Upload with progress bar using DWR (JAVA)

In this tutorial we will create a common file upload component that shows upload progress using DWR like below screenshots.

Technology used:
DWR – Direct Web Remoting - http://directwebremoting.org/
Apache commons-fileupload - http://commons.apache.org/fileupload/
Jsp/Servlet
Core java





We have to extends/implements following classes/interfaces.

org.apache.commons.fileupload.disk.DiskFileItem
org.apache.commons.fileupload.disk.DiskFileItemFactory
java.io.OutputStream
We also have to create one listener that will be notified when bytes are written on disk.
com.upload.UploadListener
Then finally we have to create one classes that will be exposed in javascript by DWR.
com.upload.UploadMonitor
Screenshots:

First we will create UploadUtil.jsp file that will display the input file box like below.

<iframe name="target_upload" id="target_upload" src='' style='display: none'>iframe>
<form name="form1" id="form1" enctype="multipart/form-data" action="//upload.jsp "
onsubmit="startProgress();" method="post" target="target_upload">
<div style="" style='padding-top: 5px;'>
<div id="status" style="padding-top: 5px;">div>
<div id='div_file' style='display: none; padding-top: 5px;'>
<input type="file" name="file1" id="file1">
<input type="submit" value="Upload" name="btn_upload" id="btn_upload">
div>
<div id='div_attach_first' name='div_attach_first' style='padding-top: 5px;'>
<a href='#' onclick='fn_attach_first(this.parentNode);'>Attach Filea>
div>
<div>

On the fn_attach_first javascript method call we have to make input file box visible

function 'fn_attach_first (obj_)
{
if(obj_)
obj_.style.display = 'none';
if(!document.getElementById("file1"))
{
var file1 = document.createElement("input");
file1.type = "file";
file1.id = "file1";
file1.name = "file1";
//document.getElementById("div_file").insertBefore(document.createElement("br"), document.getElementById("btn_upload"));
document.getElementById("div_file").insertBefore(file1, document.getElementById("btn_upload"));
}
document.getElementById('div_file').style.display = '';
}

After that we will create html div for displaying progress bar.

<div id="progressBar" style="display: none; float: left;">
<div id="theMeter" style='float: left;'>
<table><tr><td>
<div id="progressBarBox" style='float: left;'>
<div id="progressBarBoxContent">div>
div>
td><td>
<div id="progressBarText" style='padding-left: 5px; float: left;'>div>
td><td>
<div style='padding-left: 5px;' style='float: left;'>
<a href='#' onclick='fn_cancel_upload();'>Cancela>
div>
td>tr>table>
<input type='hidden' name='upload_id' id='upload_id' value=''>
div>
div>

We have to hide input file box and make progress bar visible on submitting the form using following javascript code.

function startProgress()
{
//alert("in startProgress");
if(document.getElementById('file1').value=="")
return;
//document.getElementById('btn_upload').style.display = 'none';
//document.getElementById('file1').style.display = 'none';
document.getElementById('div_file').style.display = 'none';
document.getElementById('progressBar').style.display = 'block';
//document.getElementById('progressBarText').innerHTML = 'upload in progress: 0%';
document.getElementById('progressBarText').innerHTML = "0" + '%';
//document.getElementById('btn_upload').disabled = true;
var_timeout = window.setTimeout("refreshProgress()", 1500);
return true;
}

We also have to call refereshProgress javascript function every 1500 miliseconds to update the progress using DWR.

function refreshProgress()
{
//alert("in refreshProgress");
UploadMonitor.getUploadInfo(updateProgress);
}
Following javascript function is a callback functions that will be invoked by DWR.
function updateProgress(uploadInfo)
{ //alert("in updateProgress.... uploadInfo = "+uploadInfo);
//alert("uploadInfo.inProgress = "+uploadInfo.inProgress);
if(document.getElementById('upload_id').value == '')
{
document.getElementById('upload_id').value = uploadInfo.id;
//alert(document.getElementById('upload_id').value);
}
if (uploadInfo.inProgress)
{
//document.getElementById('uploadbutton').disabled = true;
var fileIndex = uploadInfo.fileIndex;
var progressPercent = Math.ceil((uploadInfo.bytesRead / uploadInfo.totalSize) * 100);
//document.getElementById('progressBarText').innerHTML = 'upload in progress: ' + progressPercent + '%';
document.getElementById('progressBarText').innerHTML = progressPercent + '%';
document.getElementById('progressBarBoxContent').style.width = parseInt(progressPercent * 3.5) + 'px';
var_timeout = window.setTimeout("refreshProgress()", 1000);
}
else
{
//document.getElementById('uploadbutton').disabled = false;
//alert("uploadInfo.id = "+uploadInfo.id);
document.getElementById('progressBarBoxContent').style.width = "350px";
//document.getElementById('progressBarText').innerHTML = 'upload in progress: ' + "100" + '%';
document.getElementById('progressBarText').innerHTML = "100" + '%';
var fileName = document.getElementById('file1').value;
//document.getElementById('status').innerHTML = document.getElementById('file1').value;
/*var div_str = "
link - "+fileName+"";
div_str = div_str + " Remove
";
*/
document.getElementById('status').innerHTML = document.getElementById('status').innerHTML
+ getUploadedDiv(uploadInfo.id, fileName);
if(document.getElementById('file1'))
document.getElementById('div_file').removeChild(document.getElementById('file1'));
/*if(document.getElementById('btn_upload'))
document.getElementById('form1').removeChild(document.getElementById('btn_upload'));
if(document.getElementById('progressBar'))
document.getElementById('form1').removeChild(document.getElementById('progressBar'));*/
document.getElementById('progressBar').style.display = "none";
document.getElementById('progressBarBoxContent').style.width = "0px";
document.getElementById('div_attach_first').style.display = "";
//document.getElementById('div_attach').style.display = "";
//alert("done");
}
return true;
}

We are submitting the form to upload.jsp. Here is the content of upload.jsp. In this file we are using commons-fileupload to read the data to be uploaded.
We also have to create java class to be exposed using DWR.

com.upload.UploadMonitor


package com.upload;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.apache.commons.fileupload.FileItem;
import uk.ltd.getahead.dwr.WebContextFactory;
public class UploadMonitor
{
public static long id;
public UploadInfo getUploadInfo()
{
HttpServletRequest req = WebContextFactory.get().getHttpServletRequest();
UploadInfo uploadInfo = null;
if (req.getSession().getAttribute("uploadInfo") != null)
{
uploadInfo = (UploadInfo) req.getSession().getAttribute("uploadInfo");
//return (UploadInfo) req.getSession().getAttribute("uploadInfo");
if(uploadInfo.getId()==null){
uploadInfo.setId(id++ + "");
id++;
}
}
else
{
uploadInfo = new UploadInfo();
//return new UploadInfo();
}
return uploadInfo;
}
}