Java Servlets Best Practices
Role of Servlets : In the context of enterprise-level application development, servlets play a major role in providing the necessary glue between web servers and enterprise-wide components. However, servlets, on their own, are applicable only for small to medium scale application development.
While embarking web based application development based on Java servlets, it is necessary to recognize the fact that HTTP servlets provide an object-oriented abstraction of various HTTP requests. Servlets are not meant for enterprise-level application development.
Less is better. In fact, in some views, a servlet should do "as little as possible."
Within a robust design, servlets are only a portion of a fully-functional on-line application. The complete application may provide many other objects and services.
Servlets are essentially "stateless." They must interact with other objects (such as sessions) to be able to track a user through a series of actions.

Release HttpSessions when finished
HttpSession objects live inside the servlet engine until:
•The application explicitly and programmatically releases it using the API, javax.servlet.http.HttpSession.invalidate (); quite often, programmatic invalidation is part of an application logout function.
•Application Server destroys the allocated HttpSession when it expires (by default, after 1800 seconds or 30 minutes).Application Server can only maintain a certain number of HttpSessions in memory. When this limit is reached, application Server serializes and swaps the allocated HttpSession to disk. In a high volume system, the cost of serializing many abandoned HttpSessions can be quite high.

Servlets are not thread-safe(reentrant) programs, and therefore can not maintain state. HttpSession objects should be used to preserve state across multiple invocations of servlets. The application developer must explicitly determine the state attributes and store these in HttpSession objects. The servlet specification recommends that only serializable objects be stored into sessions. This is necessary to allow a servlet engine to serialize sessions either for load balancing or for memory management.
Do not use SingleThreadModel
SingleThreadModel is a tag interface that a servlet can implement to transfer its re-entrancy problem to the servlet engine. As such, javax.servlet.SingleThreadModel is part of the J2EE specification. The WebSphere servlet engine handles the servlet’s re-entrancy problem by creating separate servlet instances for each user. Because this causes a great amount of system overhead, SingleThreadModel should be avoided. Developers typically use javax.servlet.SingleThreadModel to protect updateable servlet instances in a multithreaded environment. The better approach is to avoid using servlet instance variables that are updated from the servlet’s service method.
Use the HttpServlet Init method to perform expensive operations that need only be done once
Because the servlet init() method is invoked when servlet instance is loaded, it is the perfect location to carry out expensive operations that need only be performed during initialization. By definition, the init() method is thread-safe. The results of operations in the HttpServlet.init() method can be cached safely in servlet instance variables, which become read-only in the servlet service method.
Minimize use of System.out.println
Because it seems harmless, this commonly used application development legacy is overlooked for the performance problem it really is. Because System.out.println statements and similar constructs synchronize processing for the duration of disk I/O, they can significantly slow throughput.Avoid using indiscriminate System.out.println statements. One good design implementation is to tie tracing to a “final boolean” value, which when configured to false will optimize out both the check and execution of the tracing at compile time.
One historical problem with sessions in a servlet engine is that they existed only within the JVM in which the servlet engine is running. This meant that once a user had been assigned to a servlet engine, they would have to keep using that engine for their session to have continuity - meaning you could not have HTTP load balancing accross servlet engines. There are several ways to get around this limitation.
Servlets are completely managed by the host servlet engine, and inter-servlet communication is not equivalent to usual method invocation on objects
Since servlets do not maintain their own state, database connections can not be maintained across multiple execution of servlet methods. This necessitates an additional connection pooling layer. In general, any distributed application can gain singificant performance improvements by pooling connections to servers.
For scalability sake, servlets should not be used to process complex application logic. A good practice is to consider a distributed architecture, and move complex application logic into a separate layer of CORBA, RMI or EJB servers.
Object references to servlets can be obtained by using the ServletContext (deprecated in version 2.1 of the Java Servlet API Specification), but not directly. This implies that objects should not hold references to instances of servlets, but should obtain them from the host servlet engine.

Minimize synchronization in Servlets
Servlets are multi-threaded. Servlet-based applications have to recognize and handle this. However, if large sections of code are synchronized, an application effectively becomes single threaded, and throughput decreases. Using javax.servlet.SingleThreadModel, is yet another way to protect updateable servlet instance variables, but should be avoided.

Use JDBC connection pooling
To avoid the overhead of acquiring and closing JDBC connections, an application Server provides JDBC connection pooling based on JDBC 2.0. Servlets should use application Server JDBC connection pooling instead of acquiring these connections directly from the JDBC driver.
Reuse datasources for JDBC connections
In an application Server servlets acquire JDBC connections from a javax.sql.DataSource defined for the database.A javax.sql.DataSource is obtained from application Server through a JNDI naming lookup. Avoid the overhead of acquiring a javax.sql.DataSource for each SQL access. This is an expensive operation that will severely impact the performance and scalability of the application. Instead, servlets should acquire the javax.sql.DataSource in the Servlet.init() method (or some other thread-safe method) and maintain it in a common location for reuse.
Release JDBC resources when done
Failing to close and release JDBC connections can cause other users to experience long waits for connections. Although a JDBC connection that is left unclosed will be reaped and returned by Application Server after a timeout period, others may have to wait for this to occur. Close JDBC statements when you are through with them. JDBC ResultSets can be explicitly closed as well. If not explicitly closed, ResultsSets are released when their associated statements are closed. Ensure that your code is structured to close and release JDBC resources in all cases, even in exception and error conditions.
Servlets are managed by a host servlet engine. The servlet specification guarantees that a servlet is available for service against a request pointing to that servlet. However, there is no guarantee that the same instance of the servlet will be invoked against another identical request from the same or another user agent. There are several possibilities:
Based on some policy, the servlet engine might destroy and reinitialize a servlet between two consecutive and identical requests from the same or different user agents. Alternatively, the servlet engine may maintain a pool of servlet instances and execute one of the free instances in the request thread. The web server may have a load-balancing scheme under which identical requests to a servlet URI (Universal Resource Interface)) may invoke service methods of different servlet instances in different servlet engines running on two different platforms. Thus, identical requests may be serviced by different servlet instances in different Java virtual machines.
Single Interface. Although you may have a tendency at first to build many servlets with many doPosts and doGets, for complex applications you may want to limit to just one dispatching servlet.
Remember who owns what. The servlet you write can be used simulataneously by many users at the same time and each user of the servlet has a thread. Consider the user and the session one and the same. Avoid instance variables. An instance variable is any object owned by a a class. There will be only one of these per class - not one per user. In general, you can not have a user modify an instance variable because other users are also using the same variable.
Use non-shared object for elaborate applications. To build a complex servlet-based application where you would generally want to use UML and OO techniques, you need to have the servlet construct and then activate) a non-shared object. To create a non-shared object, instantiate it within a method. A non-shared object created this way can safely be object oriented - having its own instance variables. Use non-shared objects in this way to separate servlet logic from business logic.

Shared objects. Occasionally, you need to have objects that are shared among all users of a servlet. To create a shared object, set it up as in instance variable, and initialize it in the servlets init method. Remember that all instance variables of the shared object are shared. When setting values, you should use some kind of semaphore or synchronizing mechanism to serialize access among users.
Hosted by www.Geocities.ws

1