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. 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.
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.
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-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. Mediator-View architecture.
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()
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. 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. 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.
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
AskTheArchitect@sun.com. 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.