Book Home Java Enterprise in a Nutshell Search this book

5.9. Databases and Non-HTML Content

Most web applications need to communicate with a database, either to generate dynamic content or collect and store data from users, or both. With servlets, this communication is easily handled using the JDBC API described in Chapter 2, "JDBC". Thanks to JDBC and the generally sensible design of the servlet life cycle, servlets are an excellent intermediary between a database and web clients.

Most of the general JDBC principles discussed in Chapter 2, "JDBC" apply to servlets. However, servlet developers should keep a few things in mind for optimal performance. First, JDBC Connection objects can be created in the servlet's init() method. This allows the servlet to avoid reconnecting to the database (à la CGI) with each request, saving up to a second or more on every single page request. If you anticipate high volume, you may want to create several connections and rotate between them. An excellent freeware connection-pooling system is available at http://www.javaexchange.com. Or, if you're using JDBC 2.0, the javax.sql package provides a connection-pooling mechanism. Finally, if you plan on using JDBC's transaction support, you need to create individual connections for each request or obtain exclusive use of a pooled connection.

So far, all our servlets have produced standard HTML content. Of course, this is all most servlets ever do, but it's not all that they can do. Say, for instance, that your company stores a large database of PDF documents within an Oracle database, where they can be easily accessed. Now say you want to distribute these documents on the Web. Luckily, servlets can dish out any form of content that can be defined with a MIME header. All you have to do is set the appropriate content type and use a ServletOuputStream if you need to transmit binary data. Example 5-8 shows how to pull an Adobe Acrobat document from an Oracle database.

Example 5-8. A Servlet That Serves PDF Files from a Database

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

public class DBPDFReader extends HttpServlet {

  Connection con;

  public void init(ServletConfig config) throws ServletException {
    super.init(config);
    try {
      Class.forName("oracle.jdbc.driver.OracleDriver");
      con = DriverManager.getConnection("jdbc:oracle:oci7:@DBHOST", 
                                        "user", "passwd");
    }
    catch (ClassNotFoundException e) { 
      throw new UnavailableException(this, "Couldn't load OracleDriver");
    }    
    catch (SQLException e) { 
      throw new UnavailableException(this, "Couldn't get db connection");
    }    
  }

  public void doGet(HttpServletRequest req, HttpServletResponse res)
    throws ServletException, IOException {
    
    try {
      res.setContentType("application/pdf");
      ServletOutputStream out = res.getOutputStream();
     
      Statement stmt = con.createStatement();
      ResultSet rs = stmt.executeQuery(
        "SELECT PDF FROM PDF WHERE PDFID = " + req.getParameter("PDFID"));

      if (rs.next()) {
        BufferedInputStream pdfData =
          new BufferedInputStream(rs.getBinaryStream("PDF"));
        byte[] buf = new byte[4 * 1024];  // 4K buffer
        int len;
        while ((len = pdfData.read(buf, 0, buf.length)) != -1) {
          out.write(buf, 0, len);
        }
      }
      else {
        res.sendError(res.SC_NOT_FOUND);
      }
    }
    catch(SQLException e) {
      // Report it
    }
  }
}


Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.