Handling form-based file upload with GWT and the Apache Jakarta Commons FileUpload library

Uploading files to a filesystem, a remote server, a database, etc, is a frequent need in web applications.
These files are often multipart data (that is of varying types such as XML, HTML, plain text, binary … ).
With GWT, a good solution to handle this need is the use of the Apache Jakarta Commons FileUpload library.

First, generate a skeleton project using the gwt-maven-plugin archetype :

mvn archetype:generate  

Choose archetype number 298 which makes use of the gwt-maven-plugin and generates a simple hello world sample.

298: remote -> gwt-maven-plugin (Maven plugin for the Google Web Toolkit.)

You can easily import that project into Eclipse (File > Import …> Maven > Existing Maven projects).

Add the following dependency to the pom.xml file:

<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.2.2</version>
</dependency>

In the client side, modify the onModuleLoad() method of the entry point class (called Firstmodule.java in my project) and add the following code at the end :

package com.mycompany.client;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyUpEvent;
import com.google.gwt.event.dom.client.KeyUpHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.FileUpload;
import com.google.gwt.user.client.ui.FormPanel;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.mycompany.shared.FieldVerifier;

/**
 * Entry point classes define <code>onModuleLoad()</code>.
 */
public class Firstmodule implements EntryPoint {
...
 /**
   * This is the entry point method.
   */
  public void onModuleLoad() {
...
 final FormPanel form = new FormPanel();	  
    VerticalPanel vPanel = new VerticalPanel(); 
    // http://google-web-toolkit.googlecode.com/svn/javadoc/latest/com/google/gwt/user/client/ui/FileUpload.html
    form.setMethod(FormPanel.METHOD_POST);
    //The HTTP request is encoded in multipart format. 
    form.setEncoding(FormPanel.ENCODING_MULTIPART); //  multipart MIME encoding
    form.setAction("/FileUploadGreeting"); // The servlet FileUploadGreeting
    
    form.setWidget(vPanel);
    
    FileUpload fileUpload = new FileUpload();
    fileUpload.setName("uploader"); // Very important    
    vPanel.add(fileUpload);    
    
    Label maxUpload =new Label();
    maxUpload.setText("Maximum upload file size: 1MB");
    vPanel.add(maxUpload);
        
    vPanel.add(new Button("Submit", new ClickHandler() {
        public void onClick(ClickEvent event) {
                form.submit();
        }
    }));
    
    RootPanel.get("uploadContainer").add(form); 
...
}     
}

You need to add the FileUpload widget inside a FormPanel widget. Set the action (servlet) that will be called when the user submits the form.
Line 43 is very important. You need to set a name to the FileUpload widget, otherwise the upload will not work. In fact, all of the fields under the FormPanel that you want to use need to have a name so that the HttpServlet can identify them.
The HTTP request is encoded in multipart format (line 37).
The generated HTML code will contain the following line :

<form action="FileUploadGreeting" method="POST" enctype="multipart/form-data">

In the server side, create the servlet that will be called when the user clicks on the Submit button :

package com.mycompany.server.form;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Iterator;
import java.util.List;

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

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.FileUploadBase.SizeLimitExceededException;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

public class UploadFileHandler extends HttpServlet {
	
	private static final long serialVersionUID = 1L;
	
	public void doPost(HttpServletRequest request, HttpServletResponse response)
	throws ServletException, IOException {
			
	 System.out.println("Inside doPost");		
		
		// Create a factory for disk-based file items
		FileItemFactory factory = new DiskFileItemFactory();
		// Create a new file upload handler
		ServletFileUpload fileUpload  = new ServletFileUpload(factory);
		// sizeMax - The maximum allowed size, in bytes. The default value of -1 indicates, that there is no limit.
		// 1048576 bytes = 1024 Kilobytes = 1 Megabyte
		fileUpload.setSizeMax(1048576);  
		
		if (!ServletFileUpload.isMultipartContent(request)) {
		      try {
		    	
				throw new FileUploadException("error multipart request not found");
			} catch (FileUploadException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		 		  		
		try {

			List<FileItem> items = fileUpload.parseRequest(request);
			
			if (items == null) {			
                response.getWriter().write("File not correctly uploaded");
                return;
          }
			
			Iterator<FileItem> iter = items.iterator();

			while (iter.hasNext()) {
				FileItem item = (FileItem) iter.next();
				
				////////////////////////////////////////////////
				// http://commons.apache.org/fileupload/using.html								
				////////////////////////////////////////////////

				//if (item.isFormField()) {															
					String fileName = item.getName();
					System.out.println("fileName is : " + fileName);	
					String typeMime = item.getContentType();
					System.out.println("typeMime is : " + typeMime);	
					int sizeInBytes = (int) item.getSize();
					System.out.println("Size in bytes is : " + sizeInBytes);	
					//byte[] file = item.get();					
					item.write(new File("fileOutput.txt"));		        							
				//}
			}
			
			PrintWriter out = response.getWriter();
			response.setHeader("Content-Type", "text/html");
			out.println("Upload OK");
			out.flush();
			out.close();

		} catch (SizeLimitExceededException e) {
			System.out.println("File size exceeds the limit : 1 MB!!" );			
		} catch (Exception e) {
			e.printStackTrace();
			PrintWriter out = response.getWriter();
			response.setHeader("Content-Type", "text/html");
			out.println("Error");
			out.flush();
			out.close();
		}
		
	}
	
	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doPost(request, response);
	}

}

You can easily set a size limit for uploaded files (line 36). An SizeLimitExceededException exception is raised if the size exceeds the limit (line 84).
The parseRequest(…) method, line 50, returns the list of items that were submitted.
The method isFormField() determines whether or not an item is a plain form field, as opposed to a file upload. I have commented it out at line 66 because the form only contains one field, which is the uploaded file.
You can also easily get information about the uploaded file (name, size, typeMime).
In the end, i simply write the uploaded file into a new file called fileOutput.txt which is saved at the root of the project.

Update the deployment descriptor file to declare the servlet and map it to an URL:

 <!-- Upload -->
	<servlet>
		<servlet-name>FileUploadGreeting</servlet-name>
		<servlet-class>com.mycompany.server.form.UploadFileHandler</servlet-class>
	</servlet>
	
	<servlet-mapping>
		<servlet-name>FileUploadGreeting</servlet-name>
		<url-pattern>/FileUploadGreeting</url-pattern>
	</servlet-mapping>

Finally compile and run the project in GWT Development Mode. Right-click anywhere in the Project Explorer and choose “Run As -> Maven Build…” and run the “gwt:run” goal:

Here is a screenshot of the page with the FileUpload widget added:

The whole code is available on GitHub : https://github.com/longbeach/GWTCommonsFileUpload

Links :
http://www.ietf.org/rfc/rfc1867.txt

Lightning my first led with the Arduino Uno microcontroller board

And now for something new – at least for me – here is some electronics programming.
I got the chance to meet a coworker who is very much into it and he was nice enough to provide me with the basic information to get started. So the first thing I did was ordering the SparkFun inventor’s kit.
I just received it and it comes with a booklet that provides a few exercises.
That kit also contains an Arduino Uno microcontroller that you can connect to a computer through the USB port.
There is an Arduino IDE that comes with samples. These samples are programs written in C.
A program is called a sketch. You can easily upload it to the Arduino microcontroller, through the Arduino IDE menu. Here is the code (very simple) to turn on an LED for 1 second only, then off for 5 seconds, repeatedly :

void setup() {                
  // initialize the digital pin as an output.
  // Pin 13 has an LED connected on most Arduino boards:
  pinMode(13, OUTPUT);     
}

void loop() {
  digitalWrite(13, HIGH);   // set the LED on
  delay(1000);              // wait for a second
  digitalWrite(13, LOW);    // set the LED off
  delay(5000);              // wait for 5 seconds
}

Actually, these methods need to be wrapped up into a main method and you need to include WProgram.h but the Arduino IDE does it for you. A plugin for Eclipse also exists, you can find it here.
Pluging the different parts (pin headers, led, wires, resistor) to the breadboard and the Arduino board is a piece of cake :

There is one layout sheet per exercise to pin to the breadboard (on the left).

Links :
http://www.arduino.cc
http://robotmill.com/2011/02/12/arduino-basics-blink-an-led/