Programming Tutorials Browser Tutorials Articles Struts Tutorials Hibernate Tutorials

  Tutorial: Take control of the servlet environment, Part 1 - JavaWorld November 2000

Take control of the servlet environment, Part 1 - JavaWorld November 2000

Tutorial Details:

Take control of the servlet environment, Part 1
Take control of the servlet environment, Part 1
By: By Thomas E. Davis and Craig Walker
Invisibly extend the functionality of the servlet API
he ubiquitous servlet flourishes in all areas of Web development. Authors devote entire books to servlets. Almost every major Web server and application server supports them, if not directly, then through a plethora of third-party plug-ins. An integral part of the Java 2 Platform, Enterprise Edition (J2EE) framework, they provide the foundation for JavaServer Pages. If you are a Java fanatic, and your project has a Web interface, you use servlets.
Servlets are a simple concept, and the Java Servlet API reflects that. As Figure 1 illustrates, a Request object encapsulates all the data that the client passes to the server; a Response object encapsulates all the data that the server passes to the client. And a Session object stores any stateful data that needs to persist between the handshakes. That's all there is to a servlet ... almost.
Figure 1. The flow of information in a servlet
Sun's Java Servlet API does an excellent job of hiding all the dirty work from the programmer, leaving the servlet engine to manage it instead. However, the programmer occasionally needs to peek behind the curtain and twiddle the knobs. Sometimes the programmer wants to override the engine's functionality. This series will cover these issues. Over the next few months, we will explain how you can take control of your servlet environment. We will also exploit that control and demonstrate some useful real-world tricks that can increase the performance and scalability of your projects.
Take control of the servlet environment: Read the whole series!
Part 1: Invisibly extend the functionality of the servlet API
Part 2: Alternatives to servlet session management
Part 3: Beware of the cookie monster
Most servlet engines store the user's session data in memory. This prevents you from implementing a truly load-balanced farm of Web servers because each visitor must be sticky to the server that assigned him or her a session. Once a load-balancing mechanism directs a visitor to a specific server, it keeps sending that visitor back to the same server; thus, the visitor becomes stuck to a single server, rather than being rotated or balanced across all servers. To solve this problem, do you need to migrate to another servlet engine vendor or purchase a third-party solution? Absolutely not. We'll explain why in this series.
Have you ever run into the cookie subdomain bug? For example, if you access a cookie-writing page at http://drum.rudiment.net/ , then hit the same page using the address http://www.drum.rudiment.net/ , you will have two cookies with the exact same name. When you return to http://drum.rudiment.net/ and the page requests the cookie that it originally wrote, it's a toss-up as to which version the engine will return. We will crack that problem as well in this series of articles.
In Part 1, we will introduce the foundation for inserting an invisible layer of logic between the servlet engine and your servlet code. This layer will use simple and common design patterns and open the doors to many clever and powerful enhancements.
Even though Java is a young language, it already features numerous legacy issues. To avoid confusion, we must point out that the code discussed in these articles was written for, and compiled and tested with, the following API versions:
JDK 1.1
JDBC 1.22
Servlet 2.1.1
Wrappers
The secret to taking control of the servlet environment is to wrap the API. Essentially, you build an invisible wall between your servlets and the servlet engine. Because it exposes (or implements) the same API, the wrapper is invisible to the servlet and the engine.
For the purposes of this article, we will refer to the set of wrapper classes as RSEF (the rudimental servlet extension framework). This title has little meaning other than the fact that the package structure contains the word rudiment . Mainly, the acronym will eliminate the need for us to compose clever pronouns each time we refer to the framework.
From the programmer's point of view, RSEF is virtually transparent. The only RSEF-specific class that the programmer must know about is HttpServlet . In order to take advantage of RSEF, extend the RSEF HttpServlet like so:
public class MyServlet extends net.rudiment.servlet.HttpServlet
Normally, your servlet would extend the HttpServlet in the javax.servlet.http package rather than the one in net.rudiment.servlet . But the RSEF version extends the HttpServlet in javax.servlet.http and thus sandwiches itself between your servlet and the engine. This bootstraps RSEF without cluttering your code with proprietary API calls.
Figure 2. The framework sandwiches itself between your servlets and the engine
Under the covers
Once in place, the RSEF can work its magic. The first and fundamental task of RSEF is to wrap the core servlet objects. As stated above, the core objects are the Request , the Response , and the Session . So RSEF needs to have a RequestWrapper , a ResponseWrapper , and a SessionWrapper .
Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides (the so-called Gang of Four), in their book Design Patterns (see Resources ), define this behavior as the Decorator pattern. Their definition of the this pattern reads, "Attach additional responsibilities to an object dynamically." The Decorator pattern derives its strength by aggregating the target object (dynamic) rather than inheriting (static). When your servlet interacts with a Request , Response , or Session , it will actually talk to the respective wrapper classes. However, since the wrapper classes implement the same interfaces as their aggregates, the interaction is completely transparent. To take advantage of RSEF, you don't need to change your code.
In some cases, the wrapper classes also act as a Proxy. A Proxy pattern "provide[s] a surrogate ... for another object to control access to it," according to the Gang of Four. You'll see this demonstrated in future installments of this series. To see how a similar problem is tackled with the Adapter pattern, see the recent JavaWorld article entitled "Use Microsoft's Internet Information Server as a Java Servlet Engine" (direct link available in Resources ).
Figure 3. How the wrappers are organized
As you can see from Figure 3, wrapping Session requires a bit more work. Because Session is an aggregate of Request , we can't simply wrap the Request object and be done with it. We have to wrap the Session object inside the Request wrapper. Sound simple enough? Don't be fooled: it's about to get hairy.
Put it all together
In order to pull off some of the tricks we will discuss in future articles, each wrapper has to talk to its brethren. The RequestWrapper doesn't just aggregate the engine's Request and the SessionWrapper ; it also needs a handle to the ResponseWrapper . Likewise, the ResponseWrapper must communicate with the RequestWrapper . The SessionWrapper needs references to both the RequestWrapper and the ResponseWrapper .
This hodgepodge of relationships creates a rather nasty order-of-operations problem. The RequestWrapper contains the SessionWrapper , and therefore must instantiate before the SessionWrapper . In fact, the RequestWrapper shoulders the responsibility of wrapping the Session . How then do you mix and match the different flavors of wrappers?
For example, say you want to use the RequestWrapper that handles the cookie subdomain bug with the SessionWrapper that stores its state in a database. Assuming that this SessionWrapper is one of four possible implementations, you must have four different versions of that particular RequestWrapper , one for each possible session-wrapping scenario. As the number of RequestWrapper and SessionWrapper implementations increase, the number of mappings become ridiculous. It's a cut-and-paste nightmare and completely unacceptable.
If you know which RequestWrapper and SessionWrapper combination you want to use, and you are certain such a combination will accommodate the project throughout its life cycle, you can implement a hardcoded mapping. But doing so unnecessarily sacrifices flexibility.
If, on the other hand, you are unsure about which combination you wish to use and whether that mapping will be applied globally to the product, then you need to control the mappings at runtime. But how? One alternative is to use flags: simple static final values that trigger a RequestWrapper to use a specific SessionWrapper upon execution. Functional? Yes. Elegant? Not quite. There must be a better way ... and there is!
The wonderful Gang of Four comes to our aid again. The pattern we need this time is the Factory Method. As defined in Design Patterns, the Factory Method is "...an interface for creating an object ... [that] lets the class defer instantiation to the subclass." In English: rather than telling the RequestWrapper which SessionWrapper to use, you give the RequestWrapper a black box that automagically creates SessionWrappers of whichever type you desire.
The black box is a factory. Factories simply produce objects, usually of a single specific type but with a generic interface. Just as a toy factory produces toys, a SessionWrapperFactory manufactures SessionWrappers . The SessionWrapper 's creation and function are invisible to the RequestWrapper . The RequestWrapper simply asks the factory for a SessionWrapper instance, and the factory obliges.
The code
By now you might be thoroughly confused, so let's jump straight into the code. The code below illustrates the wrappers' constructor signatures:
public ResponseWrapper( HttpServletRequest request, HttpServletResponse
response )
public RequestWrapper( HttpServletRequest request, ResponseWrapper
response, SessionWrapperFactory factory )
public SessionWrapper( RequestWrapper request, ResponseWrapper respo


 

Read Tutorial at: Click here to view the tutorial

Rate Tutorial:
Take control of the servlet environment, Part 1 - JavaWorld November 2000

View Tutorial:
Take control of the servlet environment, Part 1 - JavaWorld November 2000

Related Tutorials:

Programming Java threads in the real world, Part 8
Programming Java threads in the real world, Part 8
 
Java security evolution and concepts, Part 5
Java security evolution and concepts, Part 5
 
Boost Struts with
Boost Struts with XSLT and XML
 
Jtrix: Web services beyond SOAP
Jtrix: Web services beyond SOAP
 
Create your own type 3 JDBC driver, Part 2
Create your own type 3 JDBC driver, Part 2
 
Rumble in the jungle: J2EE versus .Net, Part 1
Rumble in the jungle: J2EE versus .Net, Part 1
 
Business process automation made easy with Java, Part 1
Business process automation made easy with Java, Part 1
 
Effort on the edge, Part 1
Effort on the edge, Part 1
 
Update distributed applications
Update distributed applications
 
A first look at JavaServer Faces, Part I
A first look at JavaServer Faces, Part Learn how to implement Web-based user interfaces with JSF
 
Servlet 2.4: What's in store
Servlet 2.4: What's in store
 
Finally, getting hands in !
Finally, getting hands in !
 
Create client-side user interfaces in HTML, Part 2
Create client-side user interfaces in HTML, Part 2
 
To my mind, of few interest
To my mind, of few interest
 
good design pattern
good design pattern
 
Clustering and Load Balancing in Tomcat 5, Part 1
The latest version of the Tomcat servlet container provides clustering and load balancing capabilities that are essential for deploying scalable and robust web applications.
 
Control your test-environment with DbUnit and Anthill
The inception of the Extreme Programming methodology has brought test-driven development and continuous integration into mainstream Java development practices. Applying these techniques to Java server-side development can quickly become a nightmare if you
 
Java and Security, Part 1
Java and Security WebLogic provides a comprehensive suite of security services that can be used to protect all aspects of a domain and its deployments. These security services affect all aspects of your domain: from the lowest level provided by the Jav
 
Unclog the server bottleneck with active containers.
In server-side control architectures such as Java ServerFaces (JSF) or Struts, a majority of the control events must be handled on the server side to update the state of the control. For every user event, the entire page data is sent back to the server...
 
Open Source Web Frameworks in Java
Open Source Web Frameworks in Java Open Source Web Frameworks in Java Struts Struts Frame work is the implementation of Model-View-Controller (MVC) design pattern for the JSP. Struts is maintained as a part of Apache Jakarta project and is open
 
Site navigation
 

 

Send your comments, Suggestions or Queries regarding this site at roseindia_net@yahoo.com.

Copyright © 2006. All rights reserved.