Thursday, June 21, 2007

A simple servlet Filter for JDBC Connections

Here is an example of a servlet Filter that could be used in a web application to check out a JDBC Connection from a connection pool, keep it open for the duration of a web request, and then insure that it gets closed at the end even if an exception occurs. The implementation is similar to the open-session-in-view pattern, but in this case it is more correctly described as open-connection-in-view. Note: Because connection pool initialization varies depending on the pool provider, the initialization of the pool DataSource is left as an exercise for the reader.
package jeoftp;

import javax.servlet.Filter;
import javax.servlet.FilterConfig;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.FilterChain;
import javax.sql.DataSource;
import java.sql.Connection;

/**
 * ConnectionProviderFilter
 *
 * Provide JDBC Connections to downstream servlets and insure they
 * are cleaned up before the web request completes. Servlets can use
 * request.getAttribute(ConnectionProviderFilter.CONNECTION_ATTR)
 * to access the Connection.
 *
 * @author Jeoff Wilks
 */
public class ConnectionProviderFilter implements Filter {

  public static final String CONNECTION_ATTR = "jeoftp.ConnectionProviderFilter";

  //most connection pools provide a standard JDBC DataSource facade
  private DataSource connectionPool;

  public void init(FilterConfig filterConfig) {
    //TODO: initialize your connectionPool here
  }

  public void destroy() {
    //TODO: clean up connectionPool here
  }

  public void doFilter(ServletRequest request,
                       ServletResponse response,
                       FilterChain chain) {

    Connection connection;

    try {
      //check out a connection for this web request
      connection = connectionPool.getConnection();

      //tie it to a request attribute so other servlets can grab it
      request.setAttribute(CONNECTION_ATTR, connection);

      //let other servlets do their work
      chain.doFilter(request, response);

    //optional: roll back transaction if an exception occurs
    } catch (Exception e) {
      connection.rollback();
      throw e;

    //mandatory: insure the connection is closed
    } finally {
      if (connection != null) {
        connection.close();
      }

    }      
  }
}   

No comments: