Back from JavaOne Russia 2013

I just get back from JavaOne Russia that was held in Moscow 23-24 April 2013. JavaOne Russia is the biggest Java Conferences in Eastern Europe. The conference organization was great and there were a lot of attendees in the conference sessions.
I had the chance to present “JSF Mashups in Action” in 24 April:

"JSF Mashups in Action" session

“JSF Mashups in Action” session

I would really like to thanks all the attendees of my session, they really made the session very interactive. I also appreciate the nice feedback that I got either verbally or from the tweets about the session:
Tweets

I uploaded my JavaOne Russia 2013 session in speakerdeck.com, It is attached below:

Have a nice time

Speaking in JavaOne Russia 2013

JavaOne Russia

JavaOne Russia

The next Wednesday, Apr 24, 16:45 – 17:45, I will be speaking in JavaOne Russia about [CON1112] JSF Mashups in Action. The session will be practical, I will talk about Mashup development, common Mashup scenarios, and the current challenges of developing Mashups. I will explain how to utilize the JSF powerful component-oriented architecture and its 2.x Ajax capabilities in order to overcome most of these challenges for creating rich Mashups. In the session, I will build many interactive Web 2.0 Mashups to show how it is possible to create rich Mashups in the JavaServer Faces world with the least required Java and JavaScript code. I wish that all of you will enjoy the session. My session will be held in San Francisco Hall, Crocus Expo International Exhibition Center, Moscow:
http://eng.crocus-expo.ru/exhibitioncenter/aboutcenter.php.

Personally, it is my first time to visit Moscow, beside enjoying technical stuff, I would like to visit some tourist places in Moscow such as kremlin and Moscow Red square and may be other interesting places, any suggestions 🙂 ?

I really wish to see all of you there in JavaOne Russia!

Parsing ATOM/RSS feeds from JavaScript code using Dojo

One of the most common requirements is to parse RSS and ATOM feeds from the JavaScript code. In this post, I show you how to parse both RSS and ATOM feeds from your JavaScript code using Dojo.

Parsing ATOM feed

The next code listing is an example which loads and parses the ATOM feed from the "atom.xml" file that contains an ATOM XML.

<script type="text/javascript">
dojo.addOnLoad(function() {
	  var resultPanelID = "resultPanel";
	  
	  // Parse ATOM feed
	  dojo.xhrGet({
	     url: "atom.xml",
	     preventCache: true,
	     handleAs: "xml",
 	     load: function(xmlDoc, ioArgs){		 
	         var i = 0;
	         var output = "";
	      
	         var node = xmlDoc.getElementsByTagName("feed").item(0);
	     
	         if (node == null) {
		         console.debug("ATOM XML format is corrupted ...");		    	     
	    	     return;
	         }
	     
	         var entriesLength = node.getElementsByTagName("entry").length;
	     
			 for (i = 0; i < entriesLength; ++i) {
				var entry = node.getElementsByTagName('entry').item(i);
			 	
				var title = entry.getElementsByTagName('title').item(0).firstChild.data;
			 	var published = entry.getElementsByTagName('published').item(0).firstChild.data;			
			 	var summary = entry.getElementsByTagName('summary').item(0).firstChild.data;
			 	var link = entry.getElementsByTagName('link').item(0).getAttribute("href");
			 	
				output += '<hr><p><a target="_blank" href="' + link +'">' + title + '</a><br/>' + 
					      '<span class="smaller">' + published + '</span><br/>' + 
					      summary +
					      '</p>';
			 }
			 
		     document.getElementById(resultPanelID).innerHTML = output; 	    	
         },
         error: function(error, ioArgs){		         
	         dojo.byId(resultPanelID).innerHTML = "Error loading atom feed";
	         console.debug("failed xhrGet for ATOM URL: ", error, ioArgs);	         
    	 }
	});
});	
</script>

<div id="resultPanel"></div>

The code listing gets all the <entry> elements in the ATOM feed then gets some of the child elements of the <entry> element which are the <title>, <published>, <summary>, and <link> elements and then displays their values in the "resultPanel" DIV element.

Parsing RSS feed

The next code listing is an example which loads and parses the RSS feed from the "rss.xml" file that contains an RSS XML.

<script type="text/javascript">
dojo.addOnLoad(function() {
	  var resultPanelID = "resultPanel";
	  
	  // Parse Rss Feed
	  dojo.xhrGet({
	     url: "rss.xml",
	     preventCache: true,
	     handleAs: "xml",
	     load: function(xmlDoc, ioArgs){		 
	         var i = 0;
	         var output = "";
	      
	         var node = xmlDoc.getElementsByTagName("channel").item(0);
	     
	         if (node == null) {
		         console.debug("RSS XML format is corrupted ...");	  		    	     
	    	     return;
	         }
	     
	         var entriesLength = node.getElementsByTagName("item").length;
			 
			 for (i = 0; i < entriesLength; ++i) {
				var entry = node.getElementsByTagName('item').item(i);
			 	
				var title = entry.getElementsByTagName('title').item(0).firstChild.data;
			 	var published = entry.getElementsByTagName('pubDate').item(0).firstChild.data;			
			 	var description = entry.getElementsByTagName('description').item(0).firstChild.data;
			 	var link = entry.getElementsByTagName('link').item(0).firstChild.data;
			 	
				output += '<hr><p><a target="_blank" href="' + link +'">' + title + '</a><br/>' + 
					      '<span class="smaller">' + published + '</span><br/>' + 
					      description +
					      '</p>';
			 }
			 	
		     document.getElementById(resultPanelID).innerHTML = output; 	    	
       },
       error: function(error, ioArgs){	         
	         dojo.byId(resultPanelID).innerHTML = "Error loading Rss feed";
	         console.debug("failed xhrGet for Rss URL: ", error, ioArgs);	  	         
  	   }	  
	});
});	
</script>

<div id="resultPanel"></div>

The code listing gets all the <item> elements in the RSS feed then gets some of the child elements of the <item> element which are the <title>, <pubDate>, <description>, and <link> elements and then displays their values in the "resultPanel" DIV element.

Ajax Error Handling

In Order to return an Ajax error from the server, you need to set the response status to 500, For example if you are working with Java Servlets, your Java Servlet will return the error as follows:

public class AjaxServlet extends HttpServlet {

	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		
		try {
			// Do whatever you want to do
		} catch (Exception exception) {
			response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
	                response.getWriter().write(exception.getMessage());
	                response.flushBuffer();			
		} finally {
			// Clean up ...
		}
	}
	
}

In the client side, you can get the server error message (after checking that the readyState of the XML HTTP Request (XHR) is 4, and the status of the XHR object is 500) from the responseText of the XHR object.

If you are using a JavaScript framework (the Dojo for example): In the Dojo xhrPost API, in order to get the error message, you can get it from the ioArgs parameter of the error callback as follows:

dojo.xhrPost( {
	url: 'service URL',
	content: {},
	handleAs: 'text',
	load: function(response, ioArgs) {
		// Do something
	},
	error: function(response, ioArgs) {
		alert("Failed while doing the operation: " + ioArgs.xhr.response);
	}
});

Using the ioArgs.xhr.response, you can get the full error message from the server response, you can also get the status code from the ioArgs.xhr.status.

I wish that this advice can be useful for you in order to make Ajax error handling correctly.

Developing Weather Application using Dojo Mobile

Abstract

Dojo mobile (dojox/mobile) is one of the most powerful JavaScript frameworks that enable you to build cross mobiles web applications. It does not only contain mobile components but also it mimics the interface of the different mobile devices. Adding to this it responds to the mobile orientations. In this article, I will illustrate how to use the framework for building a weather application on the iPhone mobile.

Application Story

The application story is simple. In the weather mobile application, the user can get the current weather forecasting of a specific location. The user can do this by selecting one city from a list of available cities in the drop down and then click the “Get Information” button to get the weather information as shown in the screenshot below.

Building the weather application

In order to create the weather forecasting page, we need to know the main parts of the Dojo mobile page:

  • The Doc Type and META tags.
  • The mobile script and style includes.
  • The application pages.

The Doc Type and META Tags

The Doc type that is recommended to be used is the HTML5 doctype as shown below:

<!DOCTYPE html>

For the META tags, it is important to use the "viewport" META tag to setup cross-device layout as shown below:

<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>

The other important META tag is an iPhone specific one which is the “apple-mobile-web-app-capable”. It is recommend to be set to “yes” to make the web application runs in full-screen mode as shown below:

<meta name="apple-mobile-web-app-capable" content="yes"/>

The script and style includes

Now, we come to the script and style includes. I’m using Dojo 1.7.1 for this application; in order to include the script and the style files; this can be done as shown below:

<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/dojo/1.7.1/dojox/mobile/themes/iphone/iphone.css" rel="stylesheet"></link>

<script src="http://ajax.googleapis.com/ajax/libs/dojo/1.7.1/dojo/dojo.js" data-dojo-config="async: true"></script>

I only included the iPhone CSS file, and the dojo.js file which is loaded asynchronously for including only the resources we need to keep the application optimized.

After including the script and the style, we need to use the require statements for including the Dojo modules. I use the new Asynchronous Modules (AMD) convention for making asynchronous loading of the modules as shown below:

require(["dojox/mobile/parser", "dojo/_base/xhr", "dojox/mobile", "dojox/mobile/deviceTheme",
         "dojox/mobile/TextBox", "dojox/mobile/Button", "dojox/mobile/compat", 
	 "dijit/form/DataList", "dojox/mobile/ComboBox",
         "dojo/domReady!"], function(parser) {
			
		//...			
		parser.parse();
	});

The following modules are loaded:

  • The Dojo mobile parser "dojox/mobile/parser" for converting the HTML elements to Dojo mobile components.
  • The Dojo XHR module "dojo/_base/xhr" for allowing performing Ajax requests.
  • The Dojo mobile device theme "dojox/mobile/deviceTheme", for allowing detecting the mobile type and loading the proper theme correctly.
  • "dojox/mobile/TextBox", "dojox/mobile/Button", "dijit/form/DataList", "dojox/mobile/ComboBox", for loading the mentioned components.
  • The "dojox/mobile/compat" module is required for allowing having cross mobiles CSS3 animations.
  • "dojo/domReady!" module is a replacement for the old dojo.ready API. The exclamation mark is required to tell Dojo not to execute the callback until the DOM is ready.

Finally in the callback, I’m using only the first parameter which is the parser object. The parser.parse statement is called for allowing the Dojo mobile parser to convert the HTML elements to Dojo mobile components.

The Application Pages

In our weather application, we have mainly two pages; the weather forecasting page and the about page. In order to make the pages scroll to the left and the right while navigation, we need to use the Dojo mobile views. The Dojo mobile views are normal HTML elements with the dojo type "dojox.mobile.View". To define the two views, we can do this as shown below:

<div id="weather" dojoType="dojox.mobile.View" selected="true">
	...
</div>
			
<div id="about" dojoType="dojox.mobile.View">
	...
</div>		

The main view should be marked as selected by setting the selected attribute to "true".

In the weather forecasting page, there are three main elements:

  • Heading element.
  • Combo Box of the available cities.
  • The “Get Information” button.

In order to create the heading element, you can mark an HTML element h1 with the “dojox.mobile.Heading” dojo type as follows:

<h1 dojoType="dojox.mobile.Heading">Weather
	<div dojoType="dojox.mobile.ToolBarButton" moveTo="about">About</div>		
</h1>

I included a toolbar button for moving to the other view. The moveTo attribute can have the id of the view to switch to, in our case it is the about view id.

In order to create the combo box element, we need to use two tags, one for the data which is the dijit.form.DataList, and the other for the widget itself which is the dojox.mobile.ComboBox as follows:

<select data-dojo-type="dijit.form.DataList" data-dojo-props="id:'locationList'" >
  <option selected>Cairo, Egypt</option>
  <option>Stockholm, Sweden</option>	
  <option>Vienna, Austria</option>
  <option>Madrid, Spain</option>	
  <option>Paris, France</option>
  <option>New York, USA</option>
  <option>Lima, Peru</option>
</select>

<input id="location" class="ninety" type="text" data-dojo-type="dojox.mobile.ComboBox" data-dojo-props="list:'locationList'" />

The “location” combo box is referring to the “locationList” using the list attribute.

The “Get Information” button calls the getWeatherInformation function to get the weather information as follows:

<button class="mblBlueButton full" dojoType="dojox.mobile.Button" onClick="getWeatherInformation();">Get Information</button>

The getWeatherInformation JavaScript function is calling a proxy Java Servlet that interacts with the Yahoo weather service API using dojo xhrGet.

function getWeatherInformation() {
	var selectedCode = cityMap[dijit.byId("location").value];
	
	dojo.xhrGet({
		url: "/mobileSamples/weatherProxyServlet?w=" + selectedCode,
		handleAs: "text",
		load: function(data) {
			document.getElementById("weatherResult").innerHTML = data;
		}
	});
}

The location value is read from the “location” combo box and the code of the location is retrieved from a custom JavaScript Map that I created for mapping the WOEID (Where on earth identification) to the locations.

When the HTML response is returned from the server, it is displayed directly in the "weatherResult" span.

Finally in the weather forecasting view, I embed the combo box and the button in the "dojox.mobile.RoundRect" div as follows:

<div dojoType="dojox.mobile.RoundRect" shadow="true">
	<label for="txtLocation">Select location</label> <br/>
	
	<select data-dojo-type="dijit.form.DataList" data-dojo-props="id:'locationList'" >
	  <option selected>Cairo, Egypt</option>
	  <option>Stockholm, Sweden</option>	
	  <option>Vienna, Austria</option>
	  <option>Madrid, Spain</option>	
	  <option>Paris, France</option>
	  <option>New York, USA</option>
	  <option>Lima, Peru</option>
	</select>
	
	<input id="location" class="ninety" type="text" data-dojo-type="dojox.mobile.ComboBox" data-dojo-props="list:'locationList'" /><br/><br/>
	
	<button class="mblBlueButton full" dojoType="dojox.mobile.Button" onClick="getWeatherInformation();">Get Information</button><br/><br/>
	
	<span id="weatherResult"/>
</div>

The other “about” view element is a simple one that contains description for the sample as follows:

<div id="about" dojoType="dojox.mobile.View">
	<h1 dojoType="dojox.mobile.Heading" back="back" moveTo="weather">About</h1>
	<div dojoType="dojox.mobile.RoundRect">This sample is developed by TechnicalAdvices.COM. It is powered by Dojo Mobile.</div>
</div>

It contains a heading that includes a back button using the back attribute. The back attribute should be set to id of the view element that the application navigates to when the back button is clicked.

The next code listing shows the complete code of the weather forecasting page:

<!DOCTYPE html>
<html>

<head>
	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
	<meta name="apple-mobile-web-app-capable" content="yes"/>
	<title>Welcome to the weather application</title> 
	
	<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/dojo/1.7.1/dojox/mobile/themes/iphone/iphone.css" rel="stylesheet"></link>
	<script src="http://ajax.googleapis.com/ajax/libs/dojo/1.7.1/dojo/dojo.js" data-dojo-config="async: true"></script>
	
	<script type="text/javascript">
		var cityMap = {};
		
		require(["dojox/mobile/parser", "dojo/_base/xhr", "dojox/mobile", "dojox/mobile/deviceTheme",
		         "dojox/mobile/TextBox", "dojox/mobile/Button", "dojox/mobile/compat", 
		         "dijit/form/DataList", "dojox/mobile/ComboBox",
		         "dojo/domReady!"], function(parser) {
			
					// initialize WOIDs ...
					cityMap["Cairo, Egypt"] = "1521894";
					cityMap["Stockholm, Sweden"] = "906057";
					cityMap["Vienna, Austria"] = "551801"
					cityMap["Madrid, Spain"] = "766273";
					cityMap["Paris, France"] = "615702";
					cityMap["New York, USA"] = "2459115";
					cityMap["Lima, Peru"] = "418440";
			
					parser.parse();
				});


		function getWeatherInformation() {
			var selectedCode = cityMap[dijit.byId("location").value];
			
			dojo.xhrGet({
			    url: "/mobileSamples/weatherProxyServlet?w=" + selectedCode,
			    handleAs: "text",
			    load: function(data) {
			    	document.getElementById("weatherResult").innerHTML = data;
			    }
			});
		}
	</script> 
	
	<style>
		.full {
			width:100%
		}
		
		.ninety {
			width:90%
		}		
	</style>
</head>

<body>
	<div id="weather" dojoType="dojox.mobile.View" selected="true">
		<h1 dojoType="dojox.mobile.Heading">Weather
			<div dojoType="dojox.mobile.ToolBarButton" moveTo="about">About</div>		
		</h1>
		
		<div dojoType="dojox.mobile.RoundRect" shadow="true">
			<label for="txtLocation">Select location</label> <br/>
			
			<select data-dojo-type="dijit.form.DataList" data-dojo-props="id:'locationList'" >
			  <option selected>Cairo, Egypt</option>
			  <option>Stockholm, Sweden</option>	
			  <option>Vienna, Austria</option>
			  <option>Madrid, Spain</option>	
			  <option>Paris, France</option>
			  <option>New York, USA</option>
			  <option>Lima, Peru</option>
			</select>
			
			<input id="location" class="ninety" type="text" data-dojo-type="dojox.mobile.ComboBox" data-dojo-props="list:'locationList'" /><br/><br/>
			
			<button class="mblBlueButton full" dojoType="dojox.mobile.Button" onClick="getWeatherInformation();">Get Information</button><br/><br/>
			
			<span id="weatherResult"/>
		</div>
	</div>
				
	<div id="about" dojoType="dojox.mobile.View">
		<h1 dojoType="dojox.mobile.Heading" back="back" moveTo="weather">About</h1>
		<div dojoType="dojox.mobile.RoundRect">This sample is developed by TechnicalAdvices.COM. It is powered by Dojo Mobile.</div>
	</div>					

</body>
</html>

The Backend Java Servlet

Finally, the backend Java Servlet reads the WOEID parameter and opens a URL connection to the yahoo API weather forecasting URL for getting the weather forecasting of the location as shown in the code listing below.

package servlets;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.ProtocolException;
import java.net.URL;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.sun.syndication.feed.synd.SyndEntry;
import com.sun.syndication.feed.synd.SyndFeed;
import com.sun.syndication.io.SyndFeedInput;

/**
 * <code>WeatherProxyServlet</code> is a proxy servlet that wraps Yahoo weather REST service.
 * @author hazems
 *
 */
public class WeatherProxyServlet extends HttpServlet {
	private static final long serialVersionUID = 8732370454506907957L;

	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		
		String WOEID = request.getParameter("w");
		HttpURLConnection connection = null;
		
		response.setContentType("text/html");

		PrintWriter writer = null;
		
		try {
			URL url = new URL("http://weather.yahooapis.com/forecastrss?u=c&w=" + WOEID);
			
			connection = createHTTPConnection(url);
			
			String output = getHTTPOutputResponse(connection);
			
			SyndFeedInput input = new SyndFeedInput();
			SyndFeed feed = input.build(new InputStreamReader(new ByteArrayInputStream(output.getBytes("UTF-8"))));  		
			
		    if (feed.getEntries() != null && feed.getEntries().size() > 0) {
	            SyndEntry entry = ((SyndEntry) feed.getEntries().get(0));
	                        
	            String title = entry.getTitle();
	            String description = entry.getDescription().getValue();
	            
	            if (description.contains("Invalid")) {
	            	throw new Exception(description);
	            }
	    		
	    		writer = response.getWriter();	            
	            writer.print(title + "<br/>" + description);
	        }	
		} catch (Exception exception) {
			throw new ServletException(exception.getMessage());
		} finally {
			if (connection != null) {
				connection.disconnect();
			}
			
			if (writer != null) {
				writer.flush();
	        	writer.close();		
			}
		}
	}
	
	private static HttpURLConnection createHTTPConnection(URL url) throws IOException, ProtocolException {
		HttpURLConnection conn = (HttpURLConnection) url.openConnection();
		
		conn.setDoOutput(true);
		conn.setDoInput(true);
		conn.setRequestMethod("GET"); 
		conn.setRequestProperty("Accept", "text/html"); 
		conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
		
		return conn;
	}

	private static String getHTTPOutputResponse(HttpURLConnection conn) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader((conn.getInputStream())));

		String httpOutputResponse = ""; 
		String outputLine;
		
		while ((outputLine = br.readLine()) != null) {
			httpOutputResponse += outputLine;
		}
		
		return httpOutputResponse;
	}
}

You can try the application from your iPhone by going to the following URL:
http://www.mashups4jsf.com/mobileSamples/weather.jsp

You can download the complete Eclipse project from the following URL:
https://www.ibm.com/developerworks/mydeveloperworks/blogs/hazem/resource/29052012/mobileSamples.zip

Conclusion

In this article, you learned how to build a mobile application using the Dojo mobile APIs. You know how to use the framework views, headings, and components for building the weather forecasting application.

“Ajax Status Zero” Resolution

“Ajax status is zero” is one of the hardest errors to debug especially when the Ajax readyState is 4. If we looked at the XMLHTTPRequest documentation, we will find that the readyState attribute can have one of the following values:

  • 0 “The object has been constructed.”
  • 1 “The open() method has been successfully invoked. During this state request headers can be set using setRequestHeader() and the request can be made using the send() method.”
  • 2 “All redirects (if any) have been followed and all HTTP headers of the final response have been received. Several response members of the object are now available.”
  • 3 “The response entity body is being received.”
  • 4 “The data transfer has been completed.”

This means that although the data transfer is completed, the status is not OK (not 200).

After some hours of investigation, I found that the XHR (XMLHTTPRequest) zero status means that there is a permission problem of the Ajax request. In other words, the Ajax request is trying to access a domain that the request is not authorized to access.

The actual problem was that my JavaScript JsTestDriver asynchronous test case was running on the JsTestDriver server which is using a different port other than the one that is used by the application server which hosts the Ajax servlet.

The other interesting point to mention is that I only faced this issue on Firefox 10 while in Internet Explorer 8, the Ajax request worked without any problems.

To solve this problem, I authorized the Ajax request that comes from the JsTestDriver server to access the application server by setting the "Access-Control-Allow-Origin" header from my servlet as follows.

response.setHeader("Access-Control-Allow-Origin", "http://127.0.0.1:42442");

The "http://127.0.0.1:42442" is the JsTestDriver server address from which the Ajax request is constructed and sent to the application server.

After making this workaround the scenario worked fine on all the browsers, I wish that this tip can be helpful for you.

Ajax file upload to a Java Servlet in HTML5

HTML5 comes with a great feature which is the ability to upload files using the XMLHttpRequest version 2.
Modern Gecko and WebKit browsers include a wonderful object FormData that allows combining both simple and complex form data (text and files) in the Ajax request object.

Let's show you how to do this.

In the example, we are having a form with two fields, one field represents a simple text field, and the other one represents a file field as shown in the code below.

<form id="form1">    

    <label for="sampleText">Please enter a text</label>

    <input id="sampleText" name="sampleText" type="text" /> <br/>

    <label for="sampleFile">Please select a file

    <input id="sampleFile" name="sampleFile" type="file" /> <br/>

    <input id="uploadBtn" type="button" value="Ajax Submit" onClick="performAjaxSubmit();"></input>

</form>

<script type="text/javascript">

    function performAjaxSubmit() {

        var sampleText = document.getElementById("sampleText").value;

        var sampleFile = document.getElementById("sampleFile").files[0];

        var formdata = new FormData();

        formdata.append("sampleText", sampleText);

        formdata.append("sampleFile", sampleFile);

        var xhr = new XMLHttpRequest();       

        xhr.open("POST","/fileUploadTester/FileUploader", true);

        xhr.send(formdata);

        xhr.onload = function(e) {

            if (this.status == 200) {

               alert(this.responseText);

            }

        };                    

    }   

</script>

As we see in the listed code, it is a normal old XHR code, but it has two differences:
1. The files property in the HTML5 input file, which gives you the ability to get the file(s) object(s).
2. The FormData object, which has one method called append, that allows adding any form data (text and file) to the object. The FormData object has another big advantage which is making the Ajax request “multipart/form-data” without writting any special code.

Now, Let's move to the Servlet code (Iam using Apache Commons File Upload for handling the multipart form request parsing).

public class FileUploader extends HttpServlet {

    protected void doPost(HttpServletRequest request,

                          HttpServletResponse response)

                          throws ServletException, IOException {

        String ajaxUpdateResult = "";

        try {

            List items = new ServletFileUpload(new DiskFileItemFactory()).parseRequest(request);            

            for (FileItem item : items) {

                if (item.isFormField()) {

                    ajaxUpdateResult += "Field " + item.getFieldName() + 

                    " with value: " + item.getString() + " is successfully read\n\r";

                } else {

                    String fileName = item.getName();

                    InputStream content = item.getInputStream();

                    response.setContentType("text/plain");

                    response.setCharacterEncoding("UTF-8");

                    // Do whatever with the content InputStream.

                    System.out.println(Streams.asString(content));

                    ajaxUpdateResult += "File " + fileName + " is successfully uploaded\n\r";

                }

            }

        } catch (FileUploadException e) {

            throw new ServletException("Parsing file upload failed.", e);

        }

        response.getWriter().print(ajaxUpdateResult);

    }
}

The Servlet simply parses the multipart form request and then constructs a message with the result.

Please keep in mind that this code will work with Chrome 5 and Safari 5, Firefox 4 but unfortunately will not work with IE9 because miserably IE9 does not have the FormData object, I will show later how you can achieve the same behaviour in IE9 “Iam sure you will not like it because it is much harder ;-)”.

Download the complete code from here.