JSP and Servlets: A powerful pair

 

AS MANY OF you know, Servlet technology arose from the need to replace the Web server CGI with a more efficient, cross-platform mechanism. Servlets are written entirely in the Java TM programming language and often have HTML content embedded within the code. The JavaServer PageTM (JSP) technology takes the alternate approach, providing the developer with the ability to embed special tags and Java programming language code within the HTML. So what is the current state of affairs?

When Sun introduced JSP software, some were quick to claim that Servlets had been replaced as the preferred request-handling mechanism in Web-enabled enterprise architectures. However, if I were a Servlet, I might quote the illustrious Mark Twain; "rumors of my death have been greatly exaggerated."

Although JSP technology will be a powerful successor to basic Servlets, the two have an evolutionary relationship and can be used in a cooperative and complementary manner. Furthermore, the JSP technology is a key component of the Java 2 Platform Enterprise Edition (J2EE) specification, serving as the preferred request handler/dispatcher and response mechanism. Figure 1 outlines the J2EE model and shows the JSP technology's positioning among its components and services. My goal is to examine architectural issues as they relate to JSP software and Servlets, and to discuss some effective designs while looking at the tradeoffs of each.

Figure 1

Figure 1. J2EE.

JSP Technology—Why, What, When, and How?
The JSP technology specification has grown out of a technical need to allow developers to better separate dynamic content from static template display data, and to provide the developer with a more tool-friendly environment. Once we move in this direction, we will be able to more cleanly separate the role of a Web production/HTML designer from that of a software developer. In addition, JSP technology is platform independent, unlike some of its counterparts.

Utilizing JSP technology involves the creation of a text page that is compiled into a Servlet able to respond to HTTP requests by default. These compiled pages adhere to the Servlet API (version 2.1 or later), which includes some new useful features. Pages created that adhere to the JSP software specification contain two types of entities: elements, of which there are three, directive, scripting, and action; and template data, which is everything else on the page. The elements are interpreted and processed at runtime, while the template data may simply be static content that is passed through in the response.

Under the covers, the JSP framework actually creates a special type of Servlet whose runtime form is generated from the aforementioned text page via a technique known as page compilation. Thus, the development environment is much more tool-friendly than the basic Servlet environment, because JSP involves the manipulation of custom tags within standard markup. The JSP technology is a Standard Extension, as are Servlets, and both are compatible with the Java Runtime Environment 1.1 and beyond.

Listing 1 provides a simple example of a server page that is compliant with JSP software version 1.0. Note that the version 1.0 specification introduces alternative XML syntax, and although this syntax will be preferred as the JSP technology evolves, currently it is optional.

The example in Listing 1 uses the Standard Action Type "usebean" that creates or retrieves the named class and assigns it the given id for use by the page. Expression elements are then used to retrieve data dynamically from the bean, convert the data into Strings, and create the page for display to the user. This simple example may pique your interest in how a page is ultimately transformed into a Servlet. Please refer to the JSP software specification for details.

Architectures
Before discussing architectures that we can use to build systems with these technologies, it is worth mentioning two basic ways of using the JSP technology.

The first method is what I refer to as the "page-centric" approach. This approach involves request invocations being made directly to a page with a .jsp extension. In the second method, which I call the "dispatcher" approach, a basic Servlet acts as a mediator or controller, delegating requests to .jsp pages and beans. Let's look at some examples of these architectures and discuss their tradeoffs and usage.

Page-Centric
Page-View. This basic architecture involves direct-request invocations to a server page with embedded Java programming language code and/or special tags that dynamically generate output for substitution within the HTML. This approach has many benefits. It is very easy to get started and is a low-overhead approach from a development standpoint. All of the Java programming language code may be embedded within the HTML, so changes are confined to a limited area, reducing complexity. The big tradeoff here is in the level of sophistication. As the scale of the system grows, some limitations of this approach surface, such as repeating too much business logic in the page instead of factoring out to a mediating Servlet. Also, utilizing a Servlet as a mediator facilitates a potentially cleaner separation of developer roles—see the Separation of Developer Roles sidebar for details.

Separation of Developer Roles
On any Web-based project multiple roles and responsibilities will exist.

For example, an individual who designs HTML pages fulfills a Web production role, while someone who writes software in the Java programming language fulfills a software development role.

On small-scale projects, these roles might be filled by the same individual or two individuals working closely together. On a larger project these roles will likely be filled by multiple individuals, who should not necessarily have overlapping skill sets and will be less productive if made too dependent on the workflow of the other.

If code that could be factored out to a mediating Servlet is included instead within the HTML markup, then the potential exists for individuals in the software development role and those in the Web production role to become more dependent than necessary on the progress and workflow of the other.

Figure 2

Figure 2. Mediator-View architecture.

Dispatcher
Mediator-View. Figure 2 shows the Mediator-View architecture. A Servlet acts as a mediator, working with a .jsp page and worker bean to fulfill a service request. The swimlanes in Figure 2 illustrate how each service is partitioned. The Servlet initially handles the request and delegates to a JSP software page/worker bean combination. The JSP populates bean properties from the request parameters and then uses the bean to prepare the data for presentation. The worker bean interacts with a component that is a client-side business abstraction used to complete the basic business processing. The .jsp page then retrieves the relevant state from the bean to dynamically generate the output view for display.

Using the RequestDispatcher
The Servlet API version 2.1 introduces the RequestDispatcher.
Example usage with a Servlet:

			RequestDispatcher dispatcher = getServletContext()
				.getRequestDispatcher("authComplete.jsp");
			request.setAttribute("auth", auth);
			dispatcher.forward(request, response);

This service is handled first by a basic Servlet that dispatches to a JSP software page for formatting and display. See the RequestDispatcher sidebar for details on how a Servlet handles the dispatching of a request to another resource. The JSP software page is responsible for delegating the processing of business functionality to a client-side business abstraction via a worker bean, which acts as a façade for the back-end resources. The worker bean and the business delegate reduce coupling between the client request and the ultimate back-end resource. In other words, the public interfaces need not change even if the API to the underlying resource changes. The worker beans might communicate through the business delegate with the back end via Enterprise JavaBeanTM (EJB) components running in a scalable, load-balancing container. Also, the worker beans can be combined with different JSP software pages to provide different views of the same underlying information.

An interesting aspect of these "dispatcher" designs is that they can be combined in a flexible and powerful way. For example, if you wanted each page access to be authenticated, you would have to duplicate the authentication code in each accessed .jsp page. Using a Servlet, you can authenticate in one place and forward to the relevant .jsp page. This gives a much cleaner and modular approach (see Figure 2).

The benefit of a Dispatcher approach is in the control the Servlet has over the request. Because the Servlet acts as the mediator, there is central forwarding control. This also creates a nice role separation between the lower-level coding in the Servlet and the .jsp coding. A drawback of this architecture is that it is more complex and involves more design work and more coding, because individual beans are created instead of code fragments. A very simple project might be burdened by this extra overhead, while more sophisticated efforts will benefit from the cleaner design.

Mediator-Composite View. This is a variant of the Mediator-View architecture and is useful for building systems with dynamic template text and dynamic content. As shown in Figure 3, the Servlet mediator dispatches to a page with the .jsp extension, which imports static and dynamic resources. A static resource might be an HTML fragment that represents a page header or footer. A dynamic resource could be another marked-up page created with the .jsp extension. This included page might also import static and dynamic resources. Figure 3 shows this nested server page, including dynamic content generated via an invocation on a helper bean, which gets to the business processing through a delegate, which once again acts as a façade to the back-end resource that may be "wrapped" in an EJB component.

Figure 3

Figure 3. Mediator-Composite View.

The role of the delegate, as a client-side business abstraction layer, is to make business calls on the actual back-end resource, such as remote invocations on an EJB component. The role of the worker bean is to service the .jsp page, preparing data for use and dynamic presentation by the page. We create a more flexible architecture by abstracting out the worker bean and the business delegate, so that the model for the .jsp page is not actually responsible for remote invocations on business resources.

Figure 3 uses the example of a shopping site checkout page, where the user is presented with the contents of a shopping cart. The Servlet might verify the user's authentication and role before dispatching to the .jsp page. The initial page might have some standard header and footer information for the user about the process of checking out. The body of this page is generated from a nested page that could represent a fairly course-grained entity, such as the complete line-by-line inventory of the items that the cart contains. This nested page might also have some header and footer information, such as the respective tags for starting and ending a table. The body of this page is dynamically generated via indirect communication with a back-end resource.

The Servlet can have overall responsibility for the service, dispatching to the initial .jsp page via a RequestDispatcher.include() method invocation. In this case the Servlet handles the response to the client and thus has the opportunity to do any sort of clean-up after all the nested invocations are completed. Another possibility is that the initial .jsp page will handle the response, as shown in Figure 3, in which case the Servlet will have completed its work once it dispatches to the server page with a RequestDispatcher.forward() method invocation.

A side effect of implementing this architecture is that the JSP software will not need to be recompiled each time the dynamic template text changes. Such flexibility is useful, especially because the current JSP technology specification does not require pre-compilation. This flexibility does, however, come at a price because it involves runtime inclusion of text, which incurs some overhead.

Figure 4

Figure 4. Service to Workers.

Service to Workers. Figure 4 shows another dispatcher type of architecture. A service is handled first by a basic Servlet that delegates the processing of business functionality to a business delegate via a worker bean and then dispatches to a server page for formatting and display. This type of architecture might be leveraged in cases where the model can be fully populated prior to display; for example, if one wants to fully populate a model and then dispatch to a server page, which will request state from the model to dynamically generate the view.

Unlike the previous architectures, the controller Servlet interfaces initially with worker beans as opposed to a .jsp page. This architecture also provides for a cleaner separation between the view and the controller, because the .jsp page is no longer making business calls, but rather, is accessing the state of the pre-populated worker bean.

Future
Having looked at a variety of ways to use JSP technology and Servlets, it is useful to remember there are more ways to architect systems with these technologies. Utilizing XML as a formatting and conversion tool within the JSP framework is one interesting area that was not discussed. As the JSP technology evolves, XML is sure to play an ever-increasing role, along with XSL/XSLT, which allows for data transformation and conversion. Additionally, the forthcoming tag extension mechanism in version 1.1 of the specification will allow for portable extensions to the environment.

If you would like to know more about these types of architectures, have comments about those presented, or want to suggest another topic for a future column, please email your thoughts to [email protected]. We will do our best to address as many requests as possible.

TRADEMARKS: Sun, Sun Microsystems, the Sun logo, Java, JavaServer Pages (JSPs), JavaBeans, and Enterprise JavaBeans (EJBs) are trademarks or registered trademarks of Sun Microsystems Inc. in the United States and other countries. Sun Microsystems Inc. may have intellectual property rights relating to implementations of the technology described in this article, and no license of any kind is given here. Please visit www.sun.com/software/ communitysource/ for licensing information.

URLs
For more information on J2EE
java.sun.com/j2ee

The full JSP software specification
java.sun.com/products/jsp

For a detailed description of the Servlet API
java.sun.com/products/servlet/