Disclaimer

The views and opinions expressed in this blog are my own and do not necessarily reflect those of my employer. The views and opinions expressed by visitors to this blog are theirs and do not necessarily reflect my own

Monday, January 24, 2011

Accessing BLOBs and Servlets, Serving Images Stored in H2

In a previous post I looked at how to store images in a H2 database using groovy. The example served as nothing more than a little bit of fun. I just wondered how you'd go about doing it and wanted to explore how to get this done in groovy and H2, so wrote a script to load some images into the database.

After this I thought well how can we make use of these from a web application. In this post I'll take a look at how to serve up images through a servlet so that we can display them in a web page. I was more interested in the perceived speed of such a technique over storing the file on the file system and I must say it actually didn't feel that slow.

The code is as follows:
public class GetImage extends HttpServlet {

 private static final long serialVersionUID = -3505939293849012116L;

 protected void doGet(HttpServletRequest request, HttpServletResponse response) 
       throws ServletException, IOException {

  String beerId = com.google.common.base.Preconditions.checkNotNull(request.getParameter("id"));

  InitialContext ctx;
  DataSource ds = null;
  Connection connection = null;
  PreparedStatement stmt = null;

  try {
   ctx = new InitialContext();
   ds = (DataSource) ctx.lookup("java:/beerDS");
   connection = ds.getConnection();

   String sql = "select image1, image1_content_type " +
     "from beer where id = ? and rownum() = 1";

   stmt = connection.prepareStatement(sql);

   stmt.setInt(1, Integer.valueOf(beerId));
   stmt.execute();

   ResultSet rs = stmt.getResultSet();

   while (rs.next()) {
    byte[] bytes = rs.getBytes("image1");
    String contentType = rs.getString("image1_content_type");
    int length = bytes.length;
    response.setContentType(contentType);
    response.setContentLength(length);
    response.getOutputStream().write(bytes);
   }
   response.getOutputStream().flush();
   response.getOutputStream().close();

  } catch (NamingException e) {
   e.printStackTrace();
  } catch (SQLException e) {
   e.printStackTrace();
  } catch (NullPointerException npe) {
   return;
  } finally {

   if (connection != null)
    try {
     connection.close();
    } catch (SQLException e) {
     e.printStackTrace();
    }
   if (stmt != null)
    try {
     stmt.close();
    } catch (SQLException e) {
     e.printStackTrace();
    }
  }
 }
}


A few things to note include:

  • You can't write multiple images to the response, not if you wan't something that can be understood by a browser. You refer to the servlet like any other file when using the url html or dynamic content. To access the image in a html page you would use a standard img tag as follows, like in the following example :
  • 
    
  • For the link to work, you'll need an entry in your web.xml (or Guice server module configuration - which is a really kool way to get rid of web.xml entirely) that ensures theres a mapping between "/my/*" url pattern and the GetImage servlet.
  • The underlying example uses my beer database configured as a data source as described in a this post
  • You'll need to ensure there is a blob in the database for the beer with ID 22 in the beer table. See my groovy script example that looks at how to get images into the database.

1 comment:

ChrisW said...

...or you could just use Grails!