Thursday, September 30, 2010

Servlet 3.0 Uploading files

The Internet is becoming more and more about sharing data and uploading files had become nearly universal requirement for a web application. Prior to Servlet 3.0, implementing file upload successfully required external libraries or tedious input processing.

Servlet 3.0 introduces a new API to handle multipart/form-data submissions. Multipart/form-data is a content type used to submit files, non-ASCII and binary data. Here is an example of file upload servlet.

fileupload.jsp: The browser will submit data using multipart/form-data encoding when an HTML form specifies it as a value for its enctype attribute.
<form action="/file-upload" enctype="multipart/form-data" method="POST">
Submitter: <input name="submitter" type="text">
Upload File: <input name="content" type="file">
<input value="Submit" type="submit">
</form>

When submitting a form, the browser will stream the content in, all parts combined, with each part representing a field of a form. Parts are named after the input elements and separated from each other with string delimiters named boundary.

What submitted header data would look like as follows:

POST /file-upload HTTP/1.1
Content-Type: multipart/form-data; boundary=---------------------------8723974127529 Content-Length: 1231

-----------------------------8723974127529 Content-Disposition: form-data; name="submitter"

pulak -----------------------------8723974127529

Content-Disposition: form-data; name="content"; filename="bloggerpoc.txt" Content-Type: application/octet-stream

<<Some data to be uploaded>>

The new Servlet 3.0 API specifies an interface javax.servlet.http.Part for each submission part and javax.servlet.http.HttpServletRequest makes them accessible using two methods:

* getParts()
* getPart(String name)

Since parts are named, method getPart(String name) can be used to access a particular part. Alternatively, method getParts() which returns an Iterable can be used to get an Iterator over all the parts. javax.servlet.http.Part is a really simple interface which provides methods allowing to introspect each part and get its name, size, content-type, query the headers submitted with a part, delete or write part out to a disk.

fileupload servlet: A simple servlet that accepts and saves a file can be as following:

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

@WebServlet(name="UploadServlet", urlPatterns={"/file-upload"})
@MultipartConfig(location = "D://tmp")
public class MyServlet extends HttpServlet {
public void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

//get the "content" part and save it.
Part part = request.getPart("content");
part.write("file2.txt");
}
}

The Servlet 3.0 Specification introduces a new @javax.servlet.annotation.MultipartConfig annotation that helps the container identify a Servlet as capable of handling multipart/form-data requests. When this annotation is present on a Servlet, the HttpServletRequest makes the parts available.

The annotation can be used to configure location where the container should store temporary files, legal size limits on the entire request and parts, and a threshold size that triggers use of permanent storage.

@MultipartConfig annotation declares the following attributes
* location
* maxFileSize
* maxRequestSize
* fileSizeThreshold

Hope this will help.
I will cover more interesting Servlet 3.0 feature like support for Asynchronous communication next.

No comments:

Post a Comment