Monday, January 07, 2013

Reading multiple files with servlets. HTML 5.

Intro

In this example we check how to process the form having one input of file type where a user chooses several files at once. We use Servlet specification of version 3.0 which is implemented in Tomcat server 7. First of all I'd recommend to get familiar with this post to perform proper configuration of your Java application and development environment. Then.. Let's start.

The example (tutorial) application will use simple html page (JSP is not used in this example). That page has one form allowing to choose several files through one dialog and then post button to submit the data. Under the form there will be a frame where the form will return the result to.

Not to make the example too complex lets say our application will be printing the content of each file to that frame with the corresponding filenames. Once you understand how it works you may process the files in any other way rather than printing their content.

So we need to pass through several steps to accomplish the goal. They are:

Create html form

Create servlet

Process the data (read multiple files with servlet)

HTML Form

Form is the facility to post your data from your client to the server. Either you're using CGI approach or servlet like in this example you have to consider two things:

HandlerServlet is actually relative URL to be considered by the server as handler of the data that is coming from your form

enctype is the attribute which should be set to "multipart/form-data" if you're going send file content. Otherwise you'll be sending the only file names

target attribute specifies the frame the server response will be printed out to (you should have the frame with corresponding name on your page like we do)

multiple is the attribute wich should be specified if you'd like to choose several files simultaneously (not working in IE pre 10)

Now you're ready to write some server code.

Creating servlet

Writing a servlet is not a rocket science. You simply need to create new class, extend it from javax.servlet.http.HttpServlet and override some methods. We're going to override the only one - "protected void doPost(..)" which actually takes the client request wrapped with "HttpServletRequest req". Latter contains all the data we need to reach our goal (retrieve the content of the files sent from the client). So the skeleton will look like this:

Lets now distract from the java code and check what the client actually sends. To know that we need to use some traffic sniffer. I use Fiddler. So, I prepared two files and going to send them to the server (no matter we have no one yet).

If you configured your project right (as described here) you should be ale to start your project. Start it and open your page with the form. Send some files (nothing will be done on the server as we haven't implemented doPost yet).

Processing the data

The request sends the data divided by the parts. Once we get the request in the servlet we need the approach to distinguish those parts and handle each piece.

Servlet specification of version 3.0 provides convenient mechanism to parse such the parts. So let's see how to get the pieces of the request data

Collection<Part> webParts = req.getParts();

Now you have the collection of the separate parts. The last thing to we need to do is somehow print the file content and the file name. Here we encounter another pitfall of mutlipart processing. As it is seen from the capture dump both the files are assigned with the same input name "example-input" so we have to distinguish them basing on something else. The good choice is to do that by the file name. So we need to get Content-Disposition header for each retrieved part. Add the following method to your servlet: