ONJava.com -- The Independent Source for Enterprise Java
oreilly.comSafari Books Online.Conferences.

advertisement

AddThis Social Bookmark Button

Learning Servlet Filters
Pages: 1, 2, 3

Thread-Based Logging

The same trick could be applied for thread-specific logging as well:



interface ILog
{
  void log(String message);
  void log(String message, Throwable);
}

class PerThreadLog implements ILog
{
  // Hold messages on a thread by thread messages
  Hashtable threadVsMesaageVector = new Hashtable();
  
  void log(String message)
  {
    Vector messageVector =
threadVsMessageVector.get(getCurrentThread());
    messageVector.add(..)
    ..
  }
  
  void initializeMessages()
  {
    threadVsMessageVector.put(getCurrentThread(),new Vector());
  }

  void dumpMessages()
  {
    Vector messageVector =
threadVsMessageVector.removet(getCurrentThread());
    ..lock(stream) // or you can transfer this job to a lower
priority serialized thread
    ..Stream the message vector to the target destination
  }
}

Clients' View of This Logging

class Log
{
  public static log(String message)
  {
    //One would cache this object in
    //production environments
    ILog ilog = Factory.getInstance().getObject(ILog.NAME);
    ilog.log(message);
  }
}

Usage

void function1()
{
  Log.log("This is a test message");
}

Implementing Filters in Current Servlet Architectures

Filters are only going to be available in 2.3 implementations. But one would quickly realize that even in the current implementations, the majority of developers typically settle for a single base servlet solution anyway. So one could very easily incorporate this solution by making the appropriate calls at the beginning and end of the servlet and effectively acheive the same thing. Carrying this out using filters just seems natural, and also provides an additional opportunity to effect the request and response if needed.

Further Benefitting From Such Models as ADO and TDP

Using the suggested architecture here you have relieved yourself of commits and rollbacks, but you are still dealing with conenctions and other JDBC-related entities. Instead, imagine the following code segment:

void printEmployees()
{
  Hashtable args = new Hashtable();
  args.put("employee_id", "E*");
  ICollection empCollection = DataFactory.executeTransaction("GET_EMPLOYEE",args);
  IIterator empItr = empCollection.getIterator();
  for(empItr.begin();!empItr.atTheEnd();empItr.next())
  {
    Employee emp = (Employee)(empItr.getCurrent();
    System.out.println(emp);
  }
  empCollection.close();
}

Doing it this way, the DataFactory handles all of the connection details. The only thing needed is the abstract collection.close(). Not only that, but the same interface works for non-relational data sources. The rowset API of JDBC 2.0 and the connector architecture, somewhat, have some similarities to these ideas. But the concept and implementation behind this is so simple, one can implement all the abstractions outlined here in less than two weeks. Also, see how the collections actually return objects as opposed to simple rows and columns? Well, if I were to explain the details of this, that would be material for another article.

How Does This Facility Compare to Using EJBs?

One truism in program optimization is that you don't do it pre-maturely. And 80% of your time is spent on 20% of the code. Obviously, one would benefit more by effecting that 20% first. The same way, in an appication server, lots of things happen locally as opposed to distributedly. I wish EJBs addressed these local issues first before addressing the distributed issues; for example, transactions, factory services, security, representing business concepts as entities, and representing business procedures as tasks. These are fundamentally local issues, if you were to make use of them effectively. All of these are of tremendous value to the servlet tier. Becasue EJBs have extended these issues to the network model, the spec is so large that it is harder to follow all the implications. Java has come to be used so effortlessly because it minimizes the complexity of C++, while preserving the OO architecture. I believe the EJB model has grown too complex trying to address multiple constituencies (distributed transactions, object databases, object to relational mapping, etc.). As a result, it is harder to get a good EJB container that is consistent and relatively cheap. My contention is that a lightweight EJB framework has a great value for the servlet tier. And such a framework would have the following features:

  • Configuration services (a combination of JNDI + XML + XPATH )
  • Factory services (simplifying the Home interface and providing stateless and stateful)
  • Logging services
  • Data collection services (resembling the Rowset API but connecting to multiple data sources)
  • Transactional support (both 1pc and 2pc)
  • Transformation services (enabling JSP, XML and SOAP fed by the data collection services)

In systems developed with the http thin client model, clustering is always possible, either at the client machine level or user session level, providing the needed scale when the user demand increases.

References

Related Reading

Java Servlet Programming, 2nd EditionJava Servlet Programming, 2nd Edition
By Jason Hunter with William Crawford
Table of Contents
Index
Sample Chapter
Full Description

  • Newer is Better by Kevin Jones in JavaPro
    Lucid explanation of the new features of Servlets and JSP, including filters and tag libraries.

  • Servlet 2.3: New Features Exposed by Jason Hunter in Java World
    An authoritative source for the new features of the Servlets 2.3 standard. Doesn't cover new JSP, though.

  • Filter Code with Servlet 2.3 Model by Jason Hunter in Java World
    Code samples for a reusable set of filters, including file upload and visitor monitoring.

  • Servlets 2.3 Spec itself from Sun
    Mandatory (although somewhat terse) reading material for the new spec.

  • A JSP architecture for Oracle Stored Procedures by Satya Komatineni in Java Report (print version)
    Explains the TDP (Transparent Data Pipeline) architecture in a relational context.

  • Java/XML Programming for Relational Databases by Satya Komatineni in XML Journal (subscription required)
    Explains TDP again, and also pluggable transformational services and declarative conversion of relational data to XML.

  • Evolving Interfaces and Implementations for Backward Compatability by Satya Komatineni in Java Developers Journal (subscription required)
    Explains logging, configuration and factory services that have been alluded to in this article.

Satya Komatineni is the CTO at Indent, Inc. and the author of Aspire, an open source web development RAD tool for J2EE/XML.


Return to ONJava.com.