novocode.com
About Novocode.com  |  Contact  |  Site Map  |  Search

Need more information? Shop for books about Servlets at Amazon.com:

2.4 An Image Servlet

This section shows how to

  • send binary data with a Servlet

A Servlet can not only return HTML pages but any kind of text or binary data. Apart from creating dynamic HTML pages and returning data which is stored on disk another common use for Servlets is creating dynamic images. The images can use any format for which an encoder in Java is available and which the Web Clients understand.

A rather inefficient but common and easy to create image format is XPM. XPM stores uncompressed pixel data in an ASCII file which can also be included in a C program. Here is a simple XPM image:

 1:  /* XPM */
 2:  static char * x_xpm[] = {
 3:  "17 13 2 1",
 4:  " <TAB>c #000000",
 5:  "X<TAB>c #FFFFFF",
 6:  "XXXXX       XXXXX",
 7:  " XXXXX     XXXXX ",
 8:  "  XXXXX   XXXXX  ",
 9:  "   XXXXX XXXXX   ",
10:  "    XXXXXXXXX    ",
11:  "     XXXXXXX     ",
12:  "      XXXXX      ",
13:  "     XXXXXXX     ",
14:  "    XXXXXXXXX    ",
15:  "   XXXXX XXXXX   ",
16:  "  XXXXX   XXXXX  ",
17:  " XXXXX     XXXXX ",
18:  "XXXXX       XXXXX"};

The numbers in line 3 are the image width, image height, number of colors and characters per pixel. Lines 4 and 5 define the colors for the two characters " " (space) and "X". The rest of the array contains the image data, one character per pixel.

The following Servlet dynamically creates an XPM image like this one. You can specify a "color" attribute in the URL for the "X" (e.g. http://localhost:22722/servlet/XpmServlet?COLOR=FF0000 for a red "X"). If the attribute is omitted the default "FFFFFF" (white) is used.

 1:  import java.io.*;
 2:  import javax.servlet.*;
 3:  import javax.servlet.http.*;
 4:
 5:  public class XpmServlet extends HttpServlet
 6:  {
 7:    protected void doGet(HttpServletRequest req,
 8:                         HttpServletResponse res)
 9:              throws ServletException, IOException
10:    {
11:      String color = req.getParameter("color");
12:      if(color == null) color = "FFFFFF";
13:
14:      res.setContentType("image/x-pixmap");
15:      res.setHeader("pragma", "no-cache");
16:
17:      ServletOutputStream out = res.getOutputStream();
18:      out.print("/* XPM */\n"+
19:                "static char * hello_xpm[] = {\n"+
20:                "\"17 13 2 1\",\n"+
21:                "\" \tc #000000\",\n"+
22:                "\"X\tc #"+color+"\",\n"+
23:                "\"XXXXX       XXXXX\",\n"+
24:                "\" XXXXX     XXXXX \",\n"+
25:                "\"  XXXXX   XXXXX  \",\n"+
26:                "\"   XXXXX XXXXX   \",\n"+
27:                "\"    XXXXXXXXX    \",\n"+
28:                "\"     XXXXXXX     \",\n"+
29:                "\"      XXXXX      \",\n"+
30:                "\"     XXXXXXX     \",\n"+
31:                "\"    XXXXXXXXX    \",\n"+
32:                "\"   XXXXX XXXXX   \",\n"+
33:                "\"  XXXXX   XXXXX  \",\n"+
34:                "\" XXXXX     XXXXX \",\n"+
35:                "\"XXXXX       XXXXX\"};\n");
36:      out.close();
37:    }
38:  }

After retrieving the "color" parameter, the content type ("image/x-pixmap" for XPM images) and the usual "pragma: no-cache" header are set. Then a ServletOutputStream is requested for writing the response body. We have to use getOutputStream instead of getWriter because we are writing image (binary) data and not text (even though XPM is using a text format). The ServletOutputStream's print(String) method converts the Unicode String to ISO-8859-1 (an 8-bit superset of the 7-bit ASCII format which is used by XPM).