Monday, October 12, 2009

Java Servlet that returns a transparent pixel

Advertising and web analytic services use many techniques and tricks in order to track user impressions and actions. One of the common ways of tracking users is by placing an image tag on a page. The image tag generates a request to some image and in addition to serving the image some statistics is being collected. This technique is used in order to reduce integration processes to a minimum. All needed to be done, is simply to place the image tag somewhere in the HTML web page, set some parameters if desired (passed by the url of the image), and that’s it. No need to worry from JavaScript not supported or Third party cookies being blocked.

An example for such a request can look like:

<img src="www.myservice.com/count?customerId=7 />

In this example, by placing the image tag in a web page, we are making a request to the server: www.myservice.co with the parameter: customerId=7, meaning the customer that sent the request is identified in our system as “7”.

Note, that we didn’t make any call to a real image. We made a request to a Java Servlet that generates for us a transparent image of one pixel. We want the image response to be as small a possible for 2 reasons:

  • The traffic from our server back to the client will be minimal. A reduction of traffic yields a better performance as well as reduced server traffic costs.
  • We want the image to be a small as possible, so it won’t be noticed and effect the layout of the page. For this reason we also return a transparent pixel.

Let see how we dynamically create a transparent image of one pixel and serve it back to the client:

package com.bashan.blog.servlet;
import javax.imageio.ImageIO;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
public class PixelServlet extends HttpServlet {
  private BufferedImage pixel;
  public void init(ServletConfig config) throws ServletException {
    super.init(config);
    pixel = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
    pixel.setRGB(0, 0, (0xFF));
  }
  protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // Here we can do whatever logic we want   
    response.setContentType("image/png");
    OutputStream os = response.getOutputStream();
    ImageIO.write(pixel, "png", os);
  }
}

Note that when the Servlet is being initialized we create the pixel and make it transparent. On the “doGet” method we write the pixel to the outputStream of the response.

Of course, instead of serving the pixel this way, we can simply put a transparent image of a pixel in the root of our web server, and make a redirection to this pixel, but usually tracking pixels are known to be requested by lots of clients simultaneously, so in terms of performance, it is better to directly write the pixel to the stream.

Don't forget to declare and map this Servlet in your web.xml to make it usable...

No comments:

Post a Comment