Wednesday, June 2, 2010

DESIGN PATTERNS I N JAVA

Designing Enterprise Applications
with the J2EETM Platform, Second Edition
________________________________________

4.4 Web-Tier Application Framework Design
Model-View-Controller ("MVC") is the BluePrints recommended architectural design pattern for interactive applications. MVC, described in Chapter 11, organizes an interactive application into three separate modules: one for the application model with its data representation and business logic, the second for views that provide data presentation and user input, and the third for a controller to dispatch requests and control flow. Most Web-tier application frameworks use some variation of the MVC design pattern.
The MVC design pattern provides a host of design benefits. MVC separates design concerns (data persistence and behavior, presentation, and control), decreasing code duplication, centralizing control, and making the application more easily modifiable. MVC also helps developers with different skill sets to focus on their core skills and collaborate through clearly defined interfaces. For example, a J2EE application project may include developers of custom tags, views, application logic, database functionality, and networking. An MVC design can centralize control of such application facilities as security, logging, and screen flow. New data sources are easy to add to an MVC application by creating code that adapts the new data source to the view API. Similarly, new client types are easy to add by adapting the new client type to operate as an MVC view. MVC clearly defines the responsibilities of participating classes, making bugs easier to track down and eliminate.
This section describes how to use MVC to organize a J2EE Web application design using the sample application's Web Application Framework design as an example. Many of the key classes described (the controller, the templating service, the abstract action class, and so on) are usable for any application, not just for an online shopping application.
A J2EE application's Web tier serves HTTP requests. At the highest level, the Web tier does four basic things in a specific order: interprets client requests, dispatches those requests to business logic, selects the next view for display, and generates and delivers the next view. (See Figure 4.2.)
Figure 4.2 The Web-Tier Service Cycle
The Web-tier controller receives each incoming HTTP request and invokes the requested business logic operation in the application model. Based on the results of the operation and state of the model, the controller then selects the next view to display. Finally, the controller generates the selected view and transmits it to the client for presentation.
Figure 4.2 is deceptively simple. An enterprise application's Web tier commonly has the following requirements:
• An application design must have a strategy for serving current and future client types.
• A Web-tier controller must be maintainable and extensible. Its tasks include mapping requests to application model operations, selecting and assembling views, and managing screen flow. Good structure can minimize code complexity.
• Application model API design and technology selection have important implications for an application's complexity, scalability, and software quality.
• Choosing an appropriate technology for generating dynamic content improves development and maintenance efficiency.
The BluePrints best practice is to implement the Web tier of a J2EE enterprise application using an appropriate Web application framework. (See Section 4.4.5 on page 114.) The next several sections describe the general design of a J2EE application Web tier. If you choose to use a Web application framework, the following discussion will help you to understand what the framework does and how to use it. If you write your own Web-tier architectural code, the following design discussions will help you make educated decisions about how to use the technology.


4.4.1 Structuring the Web Tier
Overall structure is the most important consideration in a Web-tier design. Both the sample application and the various existing Web application frameworks implement some form of "Model 2" architecture, where a servlet manages client communication and business logic execution, and presentation resides mainly in JSP pages.
The literature on Web-tier technology in the J2EE platform frequently uses the terms "Model 1" and "Model 2" without explanation. This terminology stems from early drafts of the JSP specification, which described two basic usage patterns for JSP pages. While the terms have disappeared from the specification document, they remain in common use. Model 1 and Model 2 simply refer to the absence or presence (respectively) of a controller servlet that dispatches requests from the client tier and selects views.
A Model 1 architecture consists of a Web browser directly accessing Web-tier JSP pages. The JSP pages access Web-tier JavaBeans that represent the application model, and the next view to display (JSP page, servlet, HTML page, and so on) is determined either by hyperlinks selected in the source document or by request parameters. A Model 1 application control is decentralized, because the current page being displayed determines the next page to display. In addition, each JSP page or servlet processes its own inputs (parameters from GET or POST). In some Model 1 architectures, choosing the next page to display occurs in scriptlet code, but this usage is considered poor form. (See the design guideline Section 4.2.6.8 on page 89.)
A Model 2 architecture introduces a controller servlet between the browser and the JSP pages or servlet content being delivered. The controller centralizes the logic for dispatching requests to the next view based on the request URL, input parameters, and application state. The controller also handles view selection, which decouples JSP pages and servlets from one another. Model 2 applications are easier to maintain and extend, because views do not refer to each other directly. The Model 2 controller servlet provides a single point of control for security and logging, and often encapsulates incoming data into a form usable by the back-end MVC model. For these reasons, the Model 2 architecture is recommended for most interactive applications.
An MVC application framework can greatly simplify implementing a Model 2 application. Application frameworks such as Apache Struts and JavaServer FacesTM (see Section 4.4.5 on page 114) include a configurable front controller servlet, and provide abstract classes that can be extended to handle request dispatches. Some frameworks include macro languages or other tools that simplify application construction.
The Model 1 architecture can provide a more lightweight design for small, static applications. Model 1 architecture is suitable for applications that have very simple page flow, have little need for centralized security control or logging, and change little over time. Model 1 applications can often be refactored to Model 2 when application requirements change.
4.4.1.0.1 When to Switch from Model 1 to Model 2
JSP pages in a Model 1 application that use scripting elements, custom tags, or JavaScript to forward requests should be refactored to Model 2.
A Model 1 architecture is best when the page navigation is simple and fixed, and when a simple directory structure can represent the structure of the pages in the application. Such applications usually embed the page flow information in the links between the pages. The presence of forward in a JSP page implies that logic embedded in the page is making a decision about the next page to display.
Over time, as the application grows and changes, page flow logic accumulates. The application becomes difficult to maintain because the page flow logic is distributed across multiple pages. The best time to switch from Model 1 to Model 2 is before this maintenance problem arises. This is why it's usually best to choose Model 2 from the outset, basing the application on an existing Web controller framework that best meets application requirements. Model 1 remains a viable option for simple, static applications.


4.4.2 Web-Tier MVC Controller Design
The Model 2 architecture uses servlets for processing requests and selecting views. The Front Controller architectural design pattern centralizes an application's request processing and view selection in a single component. Each type of Web client sends requests to and receives responses from a single URL, simplifying client development. The Front Controller receives requests from the client and dispatches them to the application model. This single point of dispatch makes the Front Controller a logical place for such global facilities as security and logging. The Front Controller also selects and formats the next client view. The controller is also an application of the Mediator pattern, because it decouples view components from one another.
In the J2EE platform, a Front Controller is typically implemented as a servlet. The sample application's Front Controller servlet handles all HTTP requests. The user views, discussed in the next section, are mostly JSP pages chosen by the Front Controller.
4.4.2.1 Web-Tier Controller Design
A Web-tier MVC controller maps incoming requests to operations on the application model, and selects views based on model and session state. Web-tier controllers have a lot of duties, so they require careful design to manage complexity. Because most enterprise applications grow over time, extensibility is an important requirement. This section describes some strategies for the internal structure of a controller in the Web tier, illustrated by example code adapted from the Web Application Framework, part of the BluePrints sample application.
4.4.2.1.1 Identifying the Operation to Perform
When a controller receives an HTTP request, it needs to be able to distinguish what application operation is being requested. How can the client, for example, request that the server create a new user? There are several ways to indicate to the server which operation to perform. The more common methods include:
• Indicate the operation in a hidden form field, which a POST operation delivers to the controller; for example:



• Indicate the operation in a HTTP GET query string parameter; for example:
http://myHost/myApp/servlets/myServlet?op=createUser
• Use a servlet mapping to map all URLs with a particular suffix or base URL to a specific servlet. A servlet mapping is a deployment descriptor definition that compares request paths to a pattern and dispatches matching requests to the corresponding servlet. For example, imagine that a Web application's deployment descriptor defines the following servlet mapping:

myServlet
*.do

Imagine also that the servlet's context path is http://myServer/myApp/servlets. The servlet container would direct a request with URL http://myServer/myApp/createUser.do myServlet to myServlet, because the request URL matches the pattern *.do. Servlet myServlet can extract the requested operation's name from the request URL. Chapter 11 of the Java Servlet 2.3 specification defines servlet mappings.
Of the three options discussed here, the BluePrints recommendation is to use servlet mappings when they are available. Servlet mappings provide the most flexible way to control where to route URLs based on patterns in the URLs. Most Web application frameworks (see Section 4.4.5 on page 114) use servlet mappings to direct requests to the appropriate front controller for an application.
The sample application uses a servlet mapping to handle request URLs. The servlet container maps all request URLs matching *.do to the main Web-tier controller servlet, MainServlet.java. Another servlet mapping routes all URLs matching *.screen to the templating service, which assembles composite views.
4.4.2.1.2 Invoking Model Methods
Once the controller has determined which operation to perform, it must invoke the corresponding application model method with parameters derived from the request. A naive controller design might use a large if-then-else statement, as shown in Code Example 4.6.
if (op.equals("createUser")) {
model.createUser(request.getAttribute("user"),
request.getAttribute("pass"));
} else if (op.equals("changeUserInfo") {
// ... and so on...
}

Code Example 4.6 A Poorly Designed Controller
The if-then-else approach leads to a very large service method, which is difficult to read and still more difficult to maintain. A better approach is to use the Command pattern. The sample application defines an abstract class Action, which represents a single application model operation. A controller can look up concrete Action subclasses by name and delegate requests to them. Sample code for the abstract class Action and a concrete class CreateUserAction appears in Code Example 4.7.
// Action.java:
public abstract class Action {
protected Model model;
public Action(Model model) { this.model = model; }
public abstract String getName();
public abstract Object perform(HttpServletRequest req);
};

// CreateUserAction.java:
public class CreateUserAction extends Action {
public CreateUserAction(Model model) {
super(model);
}
public String getName() { return "createUser"; }
public Object perform(HttpServletRequest req) {
return model.createUser(req.getAttribute("user"),
req.getAttribute("pass"));
}
}

Code Example 4.7 An Abstract Action Class and a Concrete Subclass
Code Example 4.7 defines an abstract class Action, which has a name and a perform method that executes a model method corresponding to the name. For example, Action's concrete subclass CreateUserAction has the name "createUser". Its perform method invokes the model method createUser using parameters extracted from the HTTP request.
public class ControllerServlet extends HttpServlet {
private HashMap actions;
public void init() throws ServletException {
actions = new HashMap();
CreateUserAction cua = new CreateUserAction(model);
actions.put(cua.getName(), cua);
//... create and add more actions
}
public void doPost(HttpServletRequest req,
HttpServletResponse resp)
throws IOException, ServletException {

// First identify operation "op" from URL.
// method getOperation() is defined elsewhere.
String op = getOperation(req.getRequestURL());
// Then find and execute corresponding Action
Action action = (Action)actions.get(op);
Object result = null;
try {
result = action.perform(req);
} catch (NullPointerException npx) {
//... handle error condition: no such action
}
// ... Use result to determine next view (see next section)
}
//... other methods...
}

Code Example 4.8 Using a Map to Identify and Execute Actions
Code Example 4.8 shows a controller servlet that maintains a hash map of Action objects, each indexed by its name. When the servlet loads, the servlet container calls the method init, which fills the hash map with Action objects that invoke model operations. The hash map key is the name of the operation. Each time the servlet's service method receives a request, it identifies the name of the operation to perform, looks up the corresponding Action in the hash map, and executes it by invoking the Action's perform method. The Action returns a result object that the servlet uses, along with other data, to decide which view to display next. When this controller receives a request containing the name createUser, it finds an instance of CreateUserAction in the hash map. It then invokes the Action's perform method, which uses the model to create a user (as shown in Code Example 4.7).
The code samples shown in this section are greatly simplified for clarity. The Web Application Framework used by the sample application provides a full, working example of this sort of controller called MainServlet. The servlet container dispatches requests with a servlet mapping: it forwards all URLs matching *.do to the MainServlet. Code Example 4.8 demonstrates how to provide an extensible framework for dispatching client requests.
The sample application improves the extensibility of the servlet code in Code Example 4.8 even further by externalizing the map of requests to actions. The controller in the sample application initializes the actions hash map from an external XML file, which contains pairs of operation names and corresponding Action class names. The controller servlet initializes the action map with the request names and action classes referred to in the XML file. The XML file is deployed as a resource in the Web application archive. Adding a new Action is as simple as adding a concrete Action subclass to the application archive and defining a configuration file mapping that associates the request URL with the action class. An example of such a mapping appears in Code Example 4.9. With no code modification, the sample application controller servlet can dispatch requests using actions that did not even exist when the controller was written.
Dispatching service requests to the application model is only half of the Web-tier controller's job. It is also responsible for determining the next view to display.
4.4.2.1.3 Controlling Dynamic Screen Flow
The succession of views that a Web application user sees is called screen flow. A Web-tier controller controls screen flow by selecting the next view a user sees. In static Web sites, screens (usually Web pages) are statically linked to one another. By contrast, a controller dynamically chooses the "next" screen in response to both user actions and model operation results.
In this section, the term "view" means a Web resource with a URL from which Web content is available. A view might be a JSP page, a servlet, static content, or some combination of the three, assembled into a page. Typically, the "next" view to display depends on one or more of:
• The current view
• The results of any operation on the application model, returned by modelmethod invocations
• Possibly other server-side state, kept in PageContext, ServletRequest, HttpSession, and ServletContext.
For example, the next view to display after a sign on view very likely depends on:
• The current view
• The user id and password contained in the request
• The success or failure of the sign on operation, and
• Possibly other server-side state. Examples of such state might include a maximum number of allowed users (application scope), or the URL the user was trying to access (request scope). See Section 4.4.7 on page 116 for a description of state and its scope.
The controller uses this data to determine which view to display next. A Web controller "displays a view" by forwarding the request to a JSP page, servlet, or other component that renders the view in a format compatible with the client; for example, returning HTML to a browser.
The controller in the sample application uses two components to select and generate views: a screen flow manager, which selects the next view to display; and a templating service, which actually generates the view content. The controller uses the screen flow manager to select a view, and forwards the request to the templating service, which assembles and delivers a view to the client. Both the screen flow manager and the templating servlet are generic components that are usable in any Web application. The component-based design reduces component coupling, promoting code reuse and simplifying the controller design.

Figure 4.3 Web-Tier Controller OID
Figure 4.3 is an object interaction diagram that shows the Web-tier controller interacting with other Web-tier classes. The diagram shows the following sequence of calls:
1. The controller receives a POST from the client.
2. The controller creates an Action corresponding to the requested operation (as described in the previous section).
3. The controller calls the Action's perform method.
4. perform calls a model business method.
5. The controller calls the screen flow manager to select the next view to display.
6. The screen flow manager determines the next view and returns its name to the controller.
7. The controller forwards the request to the templating service, which assembles and delivers the selected view to the client.
Most request URLs map to a specific view URL. For example, the screen flow map can define that the view signoff.screen always follows request URL /signoff.do. Sometimes the next screen to display depends on model operation results, server-side state, or user activity. For example, the next view following the request URL /signin.do, which signs a user into the system, depends on whether the sign in operation succeeded.
In the sample application, an application assembler configures the screen flow manager with an XML-based file called a screen flow map. The screen flow map defines a next view name for each request URL. For dynamic view selection, a screen flow map can also map a request URL to a flow handler, which is a Java class that selects the next view programmatically. Flow handlers are typically written by component providers or application assemblers.
4.4.2.1.4 Example
The Web Application Framework screen flow map mappings.xml configures the screen flow manager. Sample application Code Example 4.9 shows a URL action mapping that uses a flow handler to determine the next view in code.


com.sun.j2ee.blueprints.petstore.controller.web.actions.SignOffHTMLAction



Code Example 4.9 Excerpt from the Sample Application Screen Flow Map
In Code Example 4.9, the url-mapping element defines a mapping for request URL /signoff.do. The action element declares an action of class Signoff-HTMLAction, which performs the business logic for this URL (signing off a user). An application assembler or a component provider wrote the action class SignoffHTMLAction to sign a user off of the application. The screen attribute tells the screen flow manager to display screen signoff.screen after the action completes.
Figure 4.4 shows the result of an HTTP POST to the URL /signoff.do.

Figure 4.4 OID of POST to Flow Handler Defined in Code Example 4.9
The servlet container deployment descriptor has a servlet mapping from pattern *.do to the controller, so when a client POSTs a request to /verifysignin.do, the following actions occur:
1. The servlet container routes the request to the controller.
2. The controller creates an instance class SignoffHTMLAction and passes the request to it.
3. The controller calls the SignoffHTMLAction's perform method.
4. The SignoffHTMLAction object calls the model method that signs the user out of the application.
5. The controller asks the screen flow manager for the next view.
6. The controller forwards the request to the URL signoff.screen.
7. The templating servlet generates and delivers the requested view (a templated JSP page) to the client, so the user receives a view indicating that signoff succeeded.
The last piece of the puzzle not yet explained is how to map a view name in the design just described to an actual Web component (JSP page, servlet, and so on). Views and templating are discussed in Section 4.4.3 on page 110.
4.4.2.2 Serving Multiple Client Types
Web applications may support only one type of client with a single protocol, or multiple clients with different protocols, security policies, presentation logic, and workflows. Web clients may include several versions of a few different browsers, MIDP clients, so-called "rich" clients with stand-alone APIs, and Web service interfaces. Long-lived applications may need to be able to handle new types of Web clients.
Each type of client needs its own controller, which specializes in the protocols for that client type. A particular type of client may also need different presentation components for form factor or other reasons.
Following are some options for how to service requests from clients that use different application-level protocols. (Web-tier clients use HTTP for transport.) Each of the following alternatives expands upon Figure 4.2 by adding flexibility and increasing complexity.
Figure 4.5 Using a Front Controller to Handle Browser Interaction
Applications with a single client type can implement a single front controller. For example, a browser-only application is shown in Figure 4.5. Its single Front Controller servlet receives HTTP requests from the browser, translates the contents of these requests into operations on the application model, and serves views of result data as HTML (or XML). Additional controllers can support new client types, as shown in Figure 4.6.

Figure 4.6 Supporting Multiple Client Types with Multiple Controllers
The multiple-controller approach in Figure 4.6 provides extensibility for any future Web client types, including those that do not yet exist. In fact, because servlets aren't limited to HTTP, this architecture can support even non-Web clients. Each controller can implement the workflow, presentation logic, and security constraints unique to its client type. Notice also that the code implementing the application model is shared by all of the controllers. This separation of model and controller ensures identical application behavior across client types and eases maintenance and testing.
Some application functionality, particularly security, can be easier to manage from a single point. Introducing a protocol router, as shown in Figure 4.7, can provide a single point of control for all Web clients, each of which still retain their own controllers.

Figure 4.7 Using a Protocol Router for Centralized Control
The protocol router in Figure 4.7 is either a servlet or servlet filter that determines the client type and dispatches the request to the appropriate controller. The router typically uses the HTTP header User-agent to determine what sort of client is requesting service. The protocol router can implement application-wide functionality such as security or logging. The client-specific controllers can implement behavior specific to each client's particular protocol.
The Front Controllers in Figure 4.7 may or may not be servlets. If the Front Controllers are servlets, the protocol router dispatches requests to them using RequestDispatcher.forward. If the protocol router is a servlet, the Front Controllers can be a layer of simple objects to which the router delegates request processing.
Note that the controller alternatives shown in the last few figures can be implemented incrementally. Each of the approaches can be built on the preceding one. The BluePrints recommendation is to adopt and adapt the alternative that most closely matches current application requirements, and add new functionality as necessary.
Templating is an application of the Composite View design pattern, discussed in Chapter 11, which builds a page from a number of independent view components.


4.4.3 Web-Tier MVC View Design
MVC views display data produced by the MVC model. View components (also known as "presentation components") in the Web tier are usually JSP pages and servlets, along with such static resources as HTML pages, PDF files, graphics, and so on. JSP pages are best used for generating text-based content, often HTML or XML. Servlets are most appropriate for generating binary content or content with variable structure. (For an in-depth explanation of appropriate technology usage, see Section 4.2.6.1 on page 82 and Section 4.2.6.4 on page 86.)
HTML browsers are very lightweight clients, so the Web tier generates and often styles dynamic content for browsers. Heavyweight clients can implement relatively more view functionality in the Client tier, and less in the Web tier. Such clients include stand-alone rich clients, application clients, and clients that use special content formats such as MacroMedia Flash or Adobe Portable Document Format (PDF).
Web-tier components are not limited to serving HTML-over-HTTP Web browsers. The Web tier may also serve MIDP clients using proprietary protocols, rich clients using XML, or Web service peers requesting services with Electronic Business XML (ebXML) or Simple Object Access Protocol (SOAP) messages. Each of these examples uses a different application-level protocol, while using HTTP for transport. A properly designed Web tier unifies access to application functionality for any client type. The Web tier also provides virtual session management for some client types.
See Chapter 3 for more on J2EE client technologies.
4.4.3.1 Templating
One typical application requirement is that application views have a common layout. A template is a presentation component that composes separate subviews into a page with a specific layout. Each subview, such as a banner, a navigation bar, or document body content, is a separate component. Views that share a template have the same layout, because the template controls the layout.
For example, Figure 4.8 shows the layout of a single page created by a template. Across the top of the page is a banner, on the left is a navigation menu, a footer appears at the bottom, and the body content occupies the remaining space.

Figure 4.8 A Template Composes Other Views into a Consistent Layout
Using templates in an application design centralizes control of the overall layout of pages in the application, easing maintenance. Changing the layout in the template file changes the page layout for the entire application. More importantly, the individual subviews (like the "Navigation Menu" in Figure 4.8) are used by reference in the template instead of by copy-and-paste. Therefore, changing a subview means changing a single source file instead of changing all the files in which that subview occurs.
Template implementation is most easily explained by example. In the sample application, a JSP page called a template file specifies the page layout. The template file is a standard JSP page that uses custom tags to include subviews into each area of the page. The template references the individual subviews by name.
Code Example 4.10 is an example from the sample application that produces the layout shown in Figure 4.8. This file, called template.jsp, is a JSP page that produces HTML. The file specifies the page layout as standard HTML tags, and includes the content of other JSP pages using the custom tag insert, shown underlined in the code example.
<%@ taglib uri="/WEB-INF/tlds/taglib.tld" prefix="template" %>


<template:insert parameter="title" />



Code Example 4.10 The Template JSP Page for the Layout Shown in Figure 4.8 The JSP page includes the page named by the insert tag's parameter attribute at the point where the tag occurs. A separate screen definitions file for the application provides values for these parameters for each screen name. The templating service is a single servlet that processes all screens. A servlet mapping routes all requests with URLs matching *.screen to a TemplateServlet, which assembles and serves the requested screen. Code Example 4.11 shows the definition of the screen called main.screen. The screen definitions file defines template.jsp as its template file and defines a series of screens. Each screen has a name and a list of values for the parameters in the template file. The templating service replaces each insert tag in the template file with the contents of the subview named by the tag's parameter attribute. For example, the templating service replaces all instances of with the contents of "/banner.jsp". The result is a fully-rendered screen. main Welcome to the BluePrints Petstore Code Example 4.11 Screen Definition of Sample Application's "Main" View The templating service described here is part of the sample application's Web Application Framework. The templating service is reusable as a component in other applications. Its design is based on the Composite View design pattern, which assembles a view from reusable subviews. For more information on the Composite View design pattern, please see Chapter 11. 4.4.4 Web-Tier MVC Model Design An MVC application model both represents business data and implements business logic. Many J2EE applications implement their application models as enterprise beans, which offer scalability, concurrency, load balancing, automatic resource management, and other benefits. Simpler J2EE applications may implement the model as a collection of Web-tier JavaBeans components used directly by JSP pages or servlets. JavaBeans components provide quick access to data, while enterprise beans provide access to shared business logic and data. Notice that the "application model" in Figure 4.5 on page 107 is generic: It implies no particular technology or tier. The application model is simply the programmatic interface to the application's business logic. Model API design and model technology selection are both important design considerations. Section 11.4.1.2 on page 369 describes MVC model design considerations and patterns. 4.4.5 Web Application Frameworks As the Model 2 architecture has become more popular, quite a number of Web-tier application frameworks have appeared. Some are vendor-specific frameworks integrated with specific servers and tools; others are freely available, open-source projects. Benefits of Web-tier application frameworks appear on page 93. Three frameworks of particular interest are: • J2EE BluePrints Web Application Framework ("WAF")--The Web Application Framework forms the infrastructure of the sample application. This framework offers a Front Controller servlet, an abstract action class for Web-tier actions, a templating service, several generic custom tags, and internationalization support. WAF demonstrates both the mechanisms and effective use of a Web-tier framework layer in an application design. It is suitable for small, non-critical applications, and for learning the principles of Web-tier application framework design and usage. • Apache Struts--Struts is a free, open-source, Web-tier application framework under development at the Apache Software Foundation. Struts is highly configurable, and has a large (and growing) feature list, including a Front Controller, action classes and mappings, utility classes for XML, automatic population of server-side JavaBeans, Web forms with validation, and some internationalization support. It also includes a set of custom tags for accessing server-side state, creating HTML, performing presentation logic, and templating. Some vendors have begun to adopt and evangelize Struts. Struts has a great deal of mindshare, and can be considered an industrial-strength framework suitable for large applications. But Struts is not yet a "standard" for which J2EE product providers can interoperably and reliably create tools. • JavaServer Faces--A Java Community Process effort (JSR-127) is currently defining a standardized Web application framework called JavaServer Faces. Current standard Web-tier technologies offer only the means for creating general content for consumption by the client. There is currently no standard server-side GUI component or dispatching model. JavaServer Faces will be an architecture and a set of APIs for dispatching requests to Web-tier model JavaBeans; for maintaining stateful, server-side representations of reusable HTML GUI components; and for supporting internationalization, validation, multiple client types, and accessibility. Standardization of the architecture and API will allow tool interoperation and the development of portable, reusable Web-tier GUI component libraries. 4.4.6 Separating Business Logic from Presentation Placing business logic and presentation code in separate software layers is good design practice. The business layer provides only application functionality, with no reference to presentation. The presentation layer presents the data and input prompts to the user (or to another system), delegating application functionality to the business layer. Separating business logic from presentation has several important benefits: • Minimizes impact of change--Business rules can be changed in their own layer, with little or no modification to the presentation layer. Application presentation or workflow can change without affecting code in the business layer. • Increases maintainability--Most business logic occurs in more than one use case of a particular application. Business logic copied and pasted between components expresses the same business rule in two places in the application. Future changes to the rule require two edits instead of one. Business logic expressed in a separate component and accessed referentially can be modified in one place in the source code, producing behavior changes everywhere the component is used. Similar benefits are achieved by reusing presentation logic with server-side includes, custom tags, and stylesheets. • Provides client independence and code reuse--Intermingling data presentation and business logic ties the business logic to a particular type of client. For example, business logic implemented in a scriptlet is not usable by a servlet or an application client; the code must be reimplemented for the other client types. Business logic that is available referentially as simple method calls on business objects can be used by multiple client types. • Separates developer roles--Code that deals with data presentation, request processing, and business rules all at once is difficult to read, especially for a developer who may specialize in only one of these areas. Separating business logic and presentation allows developers to concentrate on their area of expertise. 4.4.7 Web-Tier State Data that a Web-tier component uses to create a response is called state. Examples of such data include the inventory data needed by a JSP page that lists items for sale, the contents of an online shopping cart maintained by a servlet, and the timestamp placed on an incoming request by a servlet filter. State maintenance decisions have an enormous impact on application performance, availability, and scalability. Such decisions include choosing the tier to manage state, selecting the appropriate scope for each item of state, and effectively tracking conversational state in a distributed environment. Note that the J2EE platform specification does not require that session state be recoverable after a crash or restart of a component container. Some J2EE implementations provide, as an extension, containers that can recover session state after a restart. Choosing such an implementation can simplify application design, but makes an application less portable, because it relies on a non-standard extension. 4.4.7.1 State Scope Each item of Web-tier state has scope, which determines the accessibility and lifetime of the item. Web-tier state is accessible to servlets, servlet filters, and JSP pages. Briefly, Web-tier state can be maintained in four scopes: Application scope is "global memory" for a Web application. Application-scope state is stored in the Web container's ServletContext object. (See the caveat on using context attributes in distributable servlets on page 126.) All servlets in an application share objects in application scope. The servlet developer is responsible for thread safety when accessing objects in application scope. An inventory object in application scope, for example, is accessible to all servlets, servlet filters, and JSP pages in the application. State in application scope exists for the lifetime of the application, unless it is explicitly removed. Session scope contains data specific to a user session. HTTP is a "stateless" protocol, meaning that it has no way of distinguishing users from one another or for maintaining data on users' behalf. Session attributes are named object references that are associated with a user session. The servlet API allows a developer to create a session attribute and access or update it in subsequent requests. Session-scope state for an HttpServlet is stored in the Web container's HttpSession object (available from the HttpServletRequest argument to the service method). State in session scope is accessible to all Web components in the application and across multiple servlet invocations. However, it is accessible only within an individual user session. An online shopping cart is an example of data in session scope, because the contents of the cart are specific to a single client session and available across multiple server requests. A session ends when it is explicitly closed, when it times out after a period of inactivity, or when its container is shut down or crashes. Unless removed explicitly, state in session scope lasts until the session ends. Request scope contains data specific to an individual server request, and is discarded when the service method returns. A Web component can read or modify data in request scope and then "forward" the request to another component. The component to which the request is forwarded then has access to the state. State in request scope is stored in a ServletRequest object, so it is accessible to any component receiving the request. Note that the values of query string parameters and form variables are also in request scope. For example, when a servlet places a timestamp in a ServletRequest and then forwards the request to another servlet, the timestamp is in request scope. Page scope, applicable only to JSP pages, contains data that are only valid in the context of a single page. Page scope state is stored in a JSP page's PageContext object. When one JSP page forwards to or includes another, each page defines its own scope. Page scope state is discarded when the program flow of control exits the page. 4.4.7.2 Performance Implications of State Scope Selecting the appropriate scope for an item of state depends largely on the purpose of that item in the application. It would not make sense, for example, to place a shopping cart class in application scope, because then all shoppers would have to share the same cart. Shopping carts, because they are specific to a user session, are most appropriately kept in session scope. But shopping cart contents maintained in Client-tier cookies would be in request scope, because they would be transmitted to the Web tier with each request. Maintaining session state in cookies is discouraged, even though this approach may be more easily scalable than using session attributes. See "Avoid Using Cookies Directly," starting on page 122 for more details. Each state scope has implications for scalability, performance, and reliability. State in page or request scope is less likely to cause trouble, since such data are usually not large or long-lived enough to cause resource problems. State in application scope is usually manageable if it is read-only. Entity enterprise beans are the recommended technology for maintaining writable application-scope state. Entity beans are designed for scalable, concurrent access to shared data and logic. See Section 5.4 on page 142 for more information. State in session scope has the greatest impact on Web application scalability and performance. Separate session-scope state accumulates for each connected user, unlike application-scope state, which is shared between all users and servlets. Also, session-scope state exists across requests, unlike request-scope state, which is discarded when a response is served. 4.4.7.2.1 How the Web Container Manages Session State Application servers typically track user sessions with some combination of cookies and/or URL rewriting to store a session ID on the client. The session ID identifies the session, and the server is responsible for associating each HttpServletRequest with its corresponding HttpSession object. The J2EE server handles the details of using cookies and URL rewriting. The section "Maintaining Client State" in The J2EE Tutorial explains in detail how to manage Web-tier session state. 4.4.7.3 Web-Tier State Recommendations When using enterprise beans, it's best to maintain session state with stateful session beans in the EJB tier. For Web-only applications, maintain the state in the Web tier as session attributes (using HttpSession). The following sections discuss the rationale for these recommendations. 4.4.7.3.1 Maintain Session State with Stateful Session Beans Maintaining session state in stateful session beans is a BluePrints best practice. Web-tier components can access the session state through the stateful session bean's component interface and store just the reference as a session attribute. You can maximize the runtime performance of this approach by choosing a J2EE server product that permits use of local EJB interfaces from co-located Web components. Reasons to prefer stateful session beans over other approaches to maintaining session state include: • Thread safety--Enterprise beans are thread-safe. By contrast, sophisticated thread-safe servlets are difficult to write. • Lifecycle management--The EJB container manages the lifecycle of enterprise beans components, automatically creating new instances, and activating and passivating instances as necessary to optimize performance. • Client type neutrality--Enterprise beans can be accessed, either directly or through some sort of adapter, from multiple client types. This contrasts with HTTP session attributes, which are available only to HTTP clients. For example, the sample application stores session state in stateful session beans ShoppingClientControllerEJB and EJBClientControllerEJB. For more on stateful session beans, see Chapter 5. 4.4.7.3.2 Maintain Web-Tier Session State in Session Attributes Applications that don't use enterprise beans should maintain session state in session attributes, using HttpSession's methods getAttribute and setAttribute. These methods allow the Web container to maintain the state in a way that is most effective for that particular application and server. Session attributes free the developer from the details of session state management, and ensure portability and scalability of Web components. The alternative to using session attributes is to create your own solution. The Web container (via HttpSession) provides services such as cookie management, session IDs, and so on. Writing custom Web-tier state management code is usually redundant. Don't make work for yourself! For more guidelines, see Section 4.4.7 on page 116, and also the section "Maintaining Client State" in The J2EE Tutorial. Advantages of using session attributes include: • Easy implementation--Because the application server handles the implementation of HttpSession, the developer is freed from bothering with the details of designing, implementing, and testing code for managing session state. • Optimization--An application server's HttpSession implementation is optimized and tested for that server, and therefore will probably be more efficient and reliable than a custom solution. • Potentially richer feature set--An application server's implementation of session state management may include such features as failover, cluster support, and so on, that go beyond the base-level requirements of the J2EE platform specifications. The system architect can select a server platform with the differentiating features that best suit application requirements, while maintaining J2EE technology compatibility and portability. • Portability--The HttpSession interface is standardized, so it must pass the J2EE Compatibility Test Suite (CTS) across all J2EE-branded application servers. For more on the role of the CTS and J2EE branding, see the compatibility reference listed in "References and Resources" on page 127. • Scalability--HttpSession can most effectively manage storage of Web-tier session state in caches and/or server clusters. • Evolvability--Application server vendors are constantly improving their offerings. Servers will maintain existing interfaces for backward compatibility, even as they add features that improve performance and reliability. An HttpSession implementation that works properly today will work better tomorrow as improved server versions become available, with little or no change to the source code. But session attributes have these important disadvantages: • Limited to Web clients--The Web tier is by definition limited to servicing Web clients, so HttpSession interface is limited to HTTP communications. Other client types will require reimplementation of session state management. • Session state not guaranteed to survive Web container crashes--Some application servers maintain persistent session state or provide failover, so sessions can span container crashes or restarts. But not all servers support that functionality, because the specification doesn't require it. As a result, restarting a container can invalidate all sessions in progress, losing all of their state. If this is a problem for your application, either consider selecting a server that provides persistent sessions or session failover (which compromises portability), or consider storing session state in the EIS tier. 4.4.7.3.3 Share Data among Servlets and JSP Pages with JavaBeans Components The standard JSP tag useBean accesses an attribute in application, session, request, or page scope as a JavaBean component. Standard actions setProperty and getProperty get and set the attributes' properties using JavaBeans property accessors. Servlets have access to these attributes as well, so data shared between JSP pages and servlets is best maintained in JavaBeans classes. Code Example 4.12 shows a servlet setting a session-scope attribute of type UserDataBean, naming it UserData. public void service(HttpServletRequest req, HttpServletResponse res) throws... { HttpSession session = req.getSession(); UserDataBean userData = new userData; userData.setName("Moliere"); session.setAttribute("userData", userData); ... Code Example 4.12 Setting a Session Attribute's Value to a JavaBean Instance When servlets are called, or the same servlet is called again, it can access the UserDataBean using the method HttpSession.getAttribute, as shown in Code Example 4.13. HttpSession session = req.getSession(); UserDataBean userData = (UserDataBean)session.getAttribute("userData"); String userName = userData.getUsername(); Code Example 4.13 Accessing a Session Attribute JavaBean Instance from a Servlet A JSP page can access the UserDataBean using the standard tag useBean, as shown in Code Example 4.14. This creates the named JavaBean instance if it does not already exist. The remainder of Code Example 4.14 shows how to get or set the properties of the userData attribute by using getProperty and setProperty.
Code Example 4.14 Using JavaBean Properties in a JSP Page
These examples show how to share information between components in session scope. These techniques work similarly for application, page, and request scopes.
4.4.7.3.4 Avoid Using Cookies Directly
Avoid using cookies directly for storing session state in most applications. Implementation details of session state storage are best left to the application server. Using either a stateful session bean or a Web container's HttpSession implementation can provide reliable access to session state through a portable interface. Using the standard interface saves the development time of implementing and maintaining a custom solution.
Disadvantages to using cookies for session state include:
• Cookies are controlled by a low-level API, which is more difficult to use than the other approaches.
• All data for a session are kept on the client. Corruption, expiration, or purging of cookie files can result in incomplete, inconsistent, or missing information.
• Size limitations on cookies differ by browser type and version, but the least-common-denominator approach limits the maximum cookie size to 4,096 bytes. This limitation can be eliminated by storing just references to data (session ids, user ids, and so on) in cookies, and retrieving the data as necessary from another tier (at the cost of increased server complexity and resource usage).
• Servlets and JSP pages that rely exclusively on cookies for client-side session state will not operate properly for all clients. Cookies may not be available for many reasons: The user may have disabled them, the browser version may not support them, the browser may be behind a firewall that filters cookies, and so on.
• Because Web clients transmit to a server only those cookies that it created by that server, servers with different domain names can't share cookie data. For example, JavaPetStore.com may want to allow users to shop from their own shopping sites, as well as from JavaPetFood.com. But because JavaPetFood.com can't access JavaPetStore.com's cookies, there's no easy way to unify the shopping sessions between the two servers.
• Historically, cookie implementations in both browsers and servers have tended to be buggy, or vary in their conformance to standards. While you may have control of your servers, many people still use buggy or nonconformant versions of browsers.
• Browser instances share cookies, so users cannot have multiple simultaneous sessions.
• Cookies work only for HTTP clients, because they are a feature of the HTTP protocol. Notice that while package javax.servlet.http supports session management (via class HttpSession), package javax.servlet has no such support.
Exceptions to this guideline exist. For example, a browser cookie could contain a user's login name and locale to facilitate sign on. Because of the drawbacks described here, cookies should be used to maintain session state only when there is a clear reason to do so.


4.4.8 Distributable Web Applications
The J2EE platform provides optional support for distributed Web applications. A distributed Web application runs simultaneously in multiple Web containers. When a Web application is marked distributable in its deployment descriptor, the container may (but is not required to) create multiple instances of the servlet, in multiple JVM instances, and potentially on multiple machines. Distributing a servlet improves scalability, because it allows Web request load to be spread across multiple servers. It can also improve availability by providing transparent failover between servlet instances.
4.4.8.1 Distributed Servlet Instances
By default, only one servlet instance per servlet definition is allowed for servlets that are neither in an application marked distributable, nor implement SingleThreadModel. Servlets in applications marked distributable have exactly one servlet instance per servlet definition for each Java virtual machine (JVM). The container may create and pool multiple instances of a servlet that implements SingleThreadModel, but using SingleThreadModel is discouraged.
At any particular time, session attributes for a given session are local to a particular JVM. The distributed runtime environment therefore acts to ensure that all requests associated with a given session are handled by exactly one JVM at a time. A servlet's session state may migrate to, or be failed-over to, some other JVM between requests.
4.4.8.2 Distributed Conversational State
Distributing multiple instances of a servlet across multiple JVM instances raises the issue of how to support conversational state. If each request a user makes can be routed to a different server, how can the system track that user's session state?
J2EE product providers solve this problem in different ways. One approach, called sticky server affinity, associates a particular client with a particular servlet instance for the duration of the session. This solves the session state problem, because each session is "owned" by a particular servlet. But this approach can compromise availability, because when a servlet, JVM instance, or server crashes, all of the associated sessions can be lost. Sticky server affinity can also make load balancing more difficult, because sessions are "stuck" on the servers where they started.
Another approach to solving the distributed conversational state problem is state migration. State migration serializes and moves or copies session state between servlet instances. This solution maintains the availability benefits of servlet distribution and facilitates load balancing, because sessions can be moved from more- to less-loaded servers. But state migration can increase network traffic between clustered servers. Each time a client updates session state, all redundant copies of that state must be updated. If session state is stored in a database (as is often the case), the database can become a performance bottleneck. The containers must also cooperate to resolve simultaneous update collisions, where two clients accessing the same session (one browser window opened from another, for example) update different copies of the same session state.
The J2EE platform specification gives the J2EE product provider the opportunity to add value by solving the issue of distributed conversational state in the implementation while maintaining the consistent J2EE interface. A good solution to this problem can be a selling point for a J2EE vendor. Designers considering a Web-tier-only architecture for high-performance applications should be sure to understand how prospective J2EE product providers address this issue.
Stateful session beans are designed specifically for handling distributed conversational state, but do so in the EJB tier, rather than in the Web tier. See Section 4.4.7.3.1 for more details.
4.4.8.3 Distributable Servlet Restrictions
Servlets used in a distributable application require some additional constraints. Most are necessary conditions for session state migration. These restrictions also apply for code in JSP pages and custom tags.
• Session attributes must be either serializable or supported in distributed sessions by the Web container--The Web container must accept instances of serializable classes as session attributes. A container must also accept a few other J2EE object types as session attributes: enterprise bean home and remote references, transaction contexts (javax.transaction.UserTransaction), and the JNDI context object for java:comp/env (javax.naming.Context). For any other types, the container may throw an IllegalArgumentException to indicate that the object cannot be moved between JVMs.
Implementing Serializable in a session attribute does not guarantee that the container will use native Java serialization. The container is also not required to use any defined custom serialization methods, such as readObject or writeObject, that the class may define. It does ensure that session attribute values are preserved if the session is migrated. See Section 7.2.2 of the Java Servlet specification 2.3, and Section J2EE.6.5 of the J2EE platform specification 1.3 for more details.
• Don't store application state in static or instance variables--Web containers are not required to maintain static or instance variable values when a session migrates. Code that depends on state stored in such variables will likely not operate properly after session migration. Such state should be stored either as a session attribute, in an enterprise bean, or in a database.
• Don't use context attributes to share state between servlets--Context attributes are stored in ServletContext and are shared by all servlets in a Web application. But context attributes are specific to the JVM instance in which they were created. Servlets that communicate by sharing context attributes may not operate properly if distributed, because context attributes do not replicate between Web containers in different JVM instances. To share data between distributed servlets, place the data in a session object, store it in the EIS tier in a database or distributed cache, or use an enterprise bean.
One exception to this guideline is to use context attributes as a shared data cache between the servlets in each Web container. Cache hits and misses affect only an application's performance, not its behavior.
• Don't depend on servlet context events or HTTP session events--The Web container is not required to propagate such events between containers in a distributed environment.






CONTENTS | PREV | NEXT | INDEX
Designing Enterprise Applications
with the J2EE Platform, Second Edition
________________________________________

11.4 Architecture of the Sample Application
With an understanding of these basic architectural considerations, you are ready to examine the architecture of the sample application in detail. Recall that the application is divided into two units: a Web site that serves as a front end to the user and an order fulfillment center on the back end. The Web site follows the Model-View-Controller architecture. Its architecture also combines a number of the J2EE design patterns. The fulfillment center follows a process workflow architecture.
Figure 11.4 provides a high-level view of the major modules of the sample application and the application's relationship to its key participants.

Figure 11.4 Sample Application Architecture and Participants
This discussion does not cover every detail of these architectures; instead, it illustrates several salient points of the design. You should also refer to the Java BluePrints Web site for more detailed information on the sample application architecture and design documents, along with the latest source code.


11.4.1 Application Web Site Architecture
Developing an overall application architecture involves subdividing the application into objects or components and assigning these components to tiers, a process called object decomposition. While most components are consigned to one tier or another, some serve to connect the tiers and need to span tiers, and they must be designed accordingly.
Object design becomes important as applications grow more complex. Large scale development of object-oriented software requires frameworks that define how objects interact. The framework must enable software designs and code to be easily reused. It must also identify the responsibility of each component; that is, the division into components must ensure the unambiguous identity of what the component represents and what it must accomplish.
Additionally, for multitier enterprise applications, it is important to:
• Separate stable code from code that changes more frequently. Usually the presentation and user interface change more often than business rules and database schemas. The overall architecture should separate stable portions of the application from the more volatile parts.
• Divide development effort along skill lines. The people that comprise an enterprise development team typically represent a very diverse set of skills. There are Web page designers who do HTML layout and graphics, programmers, application domain experts, and enterprise information system resource access specialists, among others. The decomposition should result in a set of objects that can be assigned to various subteams based on their particular skills. This division of labor allows work on each object to proceed in parallel.
The MVC architecture works well for the sample application. At the highest level, the application divides into three logical categories of layers--layers that deal with presentation aspects of the application, those that deal with the business rules and data, and those that accept and interpret user requests and control the business objects to fulfill these requests.
Generally, the look and feel of the application interface changes often, its behavior changes less frequently, and business data and rules are relatively stable. Thus, objects responsible for control are often more stable than presentation objects, while business rules and data are generally the most stable of all.
Web page designers, HTML and JSP technology experts, and application administrators handle implementing presentation objects after the application has been deployed. Application developers implement control-related objects. Developers, domain experts, and database experts implement business rules and data objects.
As discussed previously, the sample application's Web site handles customer interactions. (See Section 11.2 on page 352.) The Web site presents the application's data--the product catalog--to the user in response to the user's requests. The Web site's primary responsibilities include handling user requests, retrieving and displaying product catalog data to a user's browser, and allowing users to select and purchase products.
The next phase of the design process is to partition the application into modules and objects that address the different functional requirements. The partitioning process includes deciding how to apportion the application across the different tiers of the J2EE platform, which portions of the application need to be distributed, and which should be implemented for local interaction.
The discussion begins with the functional specification for the user interface to the pet store Web site. See Figure 11.5.

Figure 11.5 Use Cases between Customer and Web Site
A customer accessing the Web site expects to see:
• Links or navigation bars to common navigational tasks
• A catalog providing an organized view of the site's contents
• A search mechanism
• A master view of catalog items
• A detail view that describes the details of a particular item
• A shopping cart view that lets customers review and modify the contents of their shopping cart
• A checkout view that displays the total order cost and allows the customer to enter billing and shipping information
• A receipt view to provide confirmation of the purchase
In addition to these user interface requirements, the application must also support some security requirements, such as allowing only properly signed-on users to access certain features while allowing all users free access to other areas of the site.
Once the functional requirements are identified, the application can be divided into modules based on functionality. Such separation reduces the dependency between modules and allows them to be developed independently. In addition, identifying interfaces between modules enables modules to be developed by third-party component providers.
In this view, the application is divided into these modules:
• A control module to create and maintain user account information, which includes a user identifier, billing, and contact information. This information is maintained in a database. The control module also creates and manages the user's shopping cart and controls the interactions with the user.
• A sign-on module to handle the user log-in process and security, such as verifying a user identifier and password
• A product catalog module that returns product information from the catalog based on a user's search criteria
• A customer module that manages a user's purchasing process and maintains account records for a customer
• A messaging module that enables the application to send and receive asynchronous messages containing purchase orders
Figure 11.6 shows how the modules in the sample application Web site relate to each other.
Figure 11.6 Functional Modules for the Sample Application Web Site
Once the application is partitioned into functional modules, the next step is to identify units of business logic, data, and presentation logic and model them as software objects. This starts with identifying the options at the highest level, then working down.
The overall design and organization of the Web site follows the Model-View-Controller architecture, while the internal design of some of its individual components follow the J2EE patterns. The application uses the MVC architecture because it provides a structure for handling complex, presentation-oriented applications.
In classic MVC architecture, views register themselves with the model for change notifications. When the model changes, it notifies a view of what changed. In the application's Web site, the nature of HTTP requires the client view to use a request-response paradigm to interact with the model on the EJB tier. Rather than using notification, model changes are reported as a response to the client view.
The sample application's Web site is a complex application. It has numerous views and pages displayed to the customer in potentially different languages, plus content may be personalized. Customers can make an array of different requests, each of which the application interprets and services, with data coming from multiple sources. The application dynamically determines the sequence of views to display to the customer.
Applying the Model-View-Controller architecture to the sample application reduces its complexity and makes it more manageable. The architecture enhances the degree to which the application can be maintained and extended. By separating business and control logic from data presentation, the architecture provides the flexibility to handle such application complexity.
In the design of the Web site application, it is first partitioned into model-view-controller layers. The application divides roughly as shown in Figure 11.7. Keep in mind that these are not clear boundaries between model, view, and controller. Application functions typically straddle these layers.
The next few sections examine the operations that are performed within and across each Model-View-Controller architecture section and their design issues. They also suggest the appropriate J2EE technologies and design patterns to handle these issues.

Figure 11.7 Model-View-Controller Architecture in Sample Application
11.4.1.1 View Layer of the Application Architecture
The sample application uses the J2EE platform technologies (servlets, JSP pages, and XML) for handling user views. In general, the application uses JSP pages for presentations where the presentation data changes rather than the structure of the presentation. The application could use servlets for graphics and other binary data representations or when it appears that data structure frequently changes. If the data already exists in XML or if it must be viewed in multiple ways, this could be handled using XML combined with XSLT.
When designing the application views, consider these key issues:
• Separate presentation logic from business and control logic.
View components should focus on presentation. It is important when designing the view portion of an application to keep logic for presenting a view separate from logic that implements business rules and logic that controls process flow. In addition, it is best to keep presentation logic modular by using view templates and helper objects to structure and build page content.
JSPs are an excellent technology for creating views for Web applications. However, it is important to use JSP pages effectively. The sample application uses JSPs for the Web site so that the JSP logic focuses on rendering the view. The application's JSP pages do not contain control logic. (A controller handles control logic.) This makes it easier to reuse the presentation logic portion of the JSP page. It is also important to avoid putting logic in embedded scriptlets.
The application uses a view helper pattern. It also encapsulates presentation logic in JSP custom tags and uses JavaBeans to hold data. Presentation logic implemented in custom tags or JavaBeans is separate from data and it is modular and reusable--it is defined in one place and used referentially from different JSPs.
• Manage page layout.
Applications usually strive for a common look and feel, and keeping page layouts similar within an application is important to establishing such a look and feel. The pages for the sample application all have the same structure: a banner across the top, a navigation menu down the left side, and a footer at the bottom. Page content appears to the right of the navigation menu, between the banner and the footer. The content of each segment is independent of the others.
Figure 11.8 shows two pages from the sample application. Notice the layout similarity between these pages: the Java Pet Store banner across the top, menu selections on the left side, and the same footer information across the bottom. Page content appears to the right of the menu. However, the content of the two pages is very different.

Figure 11.8 Two Sample Application Pages
A templating mechanism, such as a composite view design pattern used by the sample application, helps to keep page layout consistent. A template determines how to assemble view components into a single view. It consolidates page layout in one location, making it easy to change page layout in one place and have all pages remain consistent. In addition, a template, such as composite view, separates layout from content.
• Separate developer roles.
The MVC architecture provides the means to separate the work of developers who have different skill sets. For the most part, Web page authors primarily have visual design skills. They usually are graphic artists or content editors, and may not be programmers. On the other hand, programmers who know the business model, work flow, and application requirements develop the model and controller components. Separating developer roles minimizes interference among developers and lets them work independently. The application uses the view helper pattern to separate data presentation from business logic. This separation enables the Web page author to change view presentation without fear of corrupting programming logic. Likewise, programmers can implement application logic without affecting the page layout.
11.4.1.2 Model Layer of the Application Architecture
The model portion of the MVC architecture encapsulates the business objects and API for the application's functionality. The sample application uses enterprise beans to implement its business logic. Enterprise beans (and the EJB tier) are the recommended J2EE technology for implementing these business objects. Enterprise beans are preferred because of the services provided by the EJB container, particularly for applications that are transactional, distributed, and potentially scalable, and where security is important. Simpler applications with fewer needs may be able to provide their own services and may consider implementing their model as Java objects.
The design of the model portion of the application considers these issues:
• Keep the functional interface manageable.
The model for most applications consists of many cooperating business objects. As the number of business objects increases, developers have more difficulty understanding how they interact. Developers can be overwhelmed by the number of APIs exposed by these object interfaces.
A complex API can be simplified using two mechanisms--a facade class and a command pattern. A facade coordinates operations between cooperating classes. It presents a single interface to the business objects representing the application model or functionality. A facade encapsulates and hides the complexity of these business objects from clients. In addition, because their implementation details are kept hidden by a facade, the objects can change without affecting the clients. The sample application uses a session facade session bean as a single interface to other enterprise bean business objects.
A facade's effectiveness is limited, since complex applications can cause the facade's API to grow too large. This is the case with the sample application. Rather than continuing to add methods to the session facade class, the sample application implements a command pattern on top of the facade. A command pattern encapsulates each application function in a separate class. Each command instance represents a single request for an application service along with data necessary to perform the service.
• Develop code as components to promote reuse.
Application development is enhanced when developers design code to be modular, reusable components, or promote using off-the-shelf frameworks and components. Modular components are designed to be independent from other components; they are only loosely-coupled to other components. With loose coupling, changes to components have little or no impact on other components. Also, modular components are designed to do only a single function. Single- function components can be easily reused and they have no extra overhead. Off-the-shelf frameworks can serve as a backbone to which other components plug in. Both off-the-shelf frameworks and components let developers leverage the expertise of others.
• Manage data access for portability.
The sample application uses business data stored in several databases. Data could also be stored in legacy systems. Each type of data repository may have its own API. It is best if the application's business objects are not tightly coupled to a specific data persistence mechanism, because changing the underlying data store or database requires changing the data access logic in the business objects. The application uses enterprise beans with container-managed persistence because, with container-managed persistence, the EJB container handles the data access details. This decouples access to persistent data from the data's particular storage mechanism. When the application uses enterprise beans with bean-managed persistence, which it must do in certain situations, it then implements a data access object to achieve the same decoupling. A data access object encapsulates data access mechanism details so that these details are kept separate from business logic.
• Locate objects.
Enterprise beans and other components in a distributed system routinely use the Java Naming and Directory Interface (JNDI) to locate other resources and components. Lookup procedures can be complex. The application uses a service locator object to handle all the lookup details for finding distributed objects. A business object can make one call to the service locator rather than including this lookup logic itself, thus letting it focus on business logic.
• Separate developer roles.
As with view development, business component development is most effective when developer roles are separated. For example, by using container-managed persistence or having database developers implement data access objects, the application shields business logic developers from the implementation details of database access calls.
11.4.1.3 Controller Layer of the Application Architecture
The controller section of the MVC architecture controls the flow of the application and serves as the glue between the model and view--it executes business logic in the model in response to user requests and helps select the next view for display. The controller decouples data presentation from business data and logic.
It is possible to implement a controller in the client, Web, or EJB tier, or in a combination of these tiers. A client presenting only views is considered a thin client. A rich client implements views and a controller. Generally, a Web-tier controller handles HTTP requests, passing requests to an EJB-tier controller, which in turn invokes the business logic processing. A Web-tier controller also selects view components for presentation by a thin Web client.
The sample application divides controller functionality between its Web and EJB tiers, and control crosses tier boundaries. The controller receives and handles requests between the Web and EJB tiers. The application also combines a controller with a command pattern. A Web-tier front controller, implemented as a servlet, receives HTTP requests and performs functions specific to the Web tier, such as changing output encoding. All user requests flow through the front controller. The front controller, using the data in the request, extracts the type of request and converts it to the appropriate type of event object. It then passes the event to the EJB-tier controller, implemented as a session bean, which matches the event to the proper command. Ultimately, the command invokes the appropriate action on a session facade, which executes the business logic.
The application selects the next view to display entirely in the Web tier, using the screen flow manager for this task. While selection of the next view can be done in either tier, it usually is done in the Web tier.
A front controller is a good design approach because it provides a single point of contact for all application requests. It interprets requests, executes business logic, and handles security, error handling, and view selection. Centralizing application control provides a natural point for implementing application-wide services and reduces code redundancy.
Implementing a controller with a command pattern not only simplifies a session facade interface (see Section 11.4.1.2 on page 369), it also keeps the controller implementation cleaner by encapsulating event- and request-handling tasks into smaller objects. It also enables Java platform events to be used as the bridge between Web- and EJB-tier controllers.
The application's controller section includes a request intercepting filter. This servlet provides application-wide security services. The request intercepting filter handles all incoming user requests and checks that users are properly logged in. Centralizing application-wide services in one place makes it is easy to add and remove services.
11.4.1.4 Applying MVC Architecture to Web Application
The architecture for the sample application's Web site consists of a set of components divided into model, view, and controller layers. The components in the controller layer handle client requests--they receive client requests and start the process of providing the appropriate response. The controller layer components are Request Intercepting Filter, Event Controller, Event Factory, Event, EJB Tier Controller, and Command Factory.
The model layer contains the components that handle business logic: Session Facade, Business Object, and Data Access Object. They extract and formulate the data required to handle a client request. The Command Handler component straddles the controller and model layer, and serves as a bridge between them. The view layer contains the components whose job is to format and present a response to the client. It consists of the following components: Screen View, Composite View, Screen Flow Manager, and View Helper. Three additional components--Service Locator, Value Object, and Business Delegate--apply the MVC approach in a distributed setting. They handle the issues that arise in a distributed architecture.
Let's examine the architecture of the application in more detail by following a user request received by the Web site. This section shows how the model, view, and controller portions of the Web site handle the request and how different objects or components are designed to handle the application's functionality. Whenever possible, these components follow J2EE design patterns. Figure 11.9 shows how the sample application architecture decomposes into components.

Figure 11.9 Class Diagram Showing Sample Application Architectural Components
A client interacts with different views presented in the browser and eventually submits an HTTP request. The request goes to the controller section where it is handled by a Request Intercepting Filter. This servlet filter receives the request and does the necessary security checks. It then passes the request to the Front Controller servlet. The Front Controller's job is to pull out data from the request form and create an event object with that data. It uses an event factory to create the right type of event and then passes the event to an EJB Tier Controller session bean. This session bean maps the event to a command using the services of a Command Factory and a Command Handler object. A Command Handler object simplifies a session facade by determining the action to perform.
To handle the request, the Command Handler object invokes the correct action on a Session Facade, which is a session bean in the model section. The Session Facade organizes the work that needs to be done. It invokes operations on other session and entity beans, referred to as business objects, that carry out the details of the application's business logic. Entity beans may access the database if it's necessary to retrieve data. If the entity bean uses container-managed persistence, the EJB container handles the data access logic. Otherwise, if the entity bean uses bean-managed persistence, there may be an additional Data Access Object to hold the access logic.
The sample application includes an EJB Tier Controller that relies on a command handler object. The EJB Tier Controller provides a single method, handleEvent, through which requests from the Front Controller pass as events. The handleEvent method includes an event argument that encapsulates the requested operation and any required data. Based on the event type, the EJB Tier Controller uses the Command Factory to get the proper Command Handler. The Command Handler orchestrates updates to model data contained in EJB components. By using the command pattern, the EJB Tier Controller delegates the execution of business functionality to the Command Handler.
For example, the application centralizes business logic in a PlaceOrder command handler. The PlaceOrder command handler orchestrates the details of business operations in one object. The PlaceOrder command handler bean calls four different enterprise beans (both entity and session beans) to carry out its operations, such as requesting database information, preparing orders, formulating response information, building and sending XML messages, and so forth.
To present a page to the user, the application must retrieve data and then format it properly. Not only must the application build the presentation page, it must also know the correct page to display within the sequence of pages. At the data retrieval level, the application uses a Service Locator object to perform look up functions. It also uses a Business Delegate to bridge the EJB and Web tiers, particularly if its entity beans are implemented with a remote client view. The Business Delegate is an object that hides the data retrieval details, such as remote exceptions. A Value Object may be used to limit the number of remote access calls.
Other components take care of the presentation of the retrieved data. The Screen View is a JSP page that builds the next screen to display to the user. It relies on a Composite View, which is a template containing the page structure (header, footer, and so forth). It also relies on a View Helper, either a JavaBean component or a helper object, that extracts the dynamic content for the page from the retrieved data. The Screen Flow Manager object keeps track of the next page in the sequence of pages.
Figure 11.9 reflects a remote view architecture. In actuality, the sample application Web site uses a local architecture approach. While this approach limits distribution to one VM, it does provide increased performance and the ability to have fine-grained method access. It also enables the application to leverage all the container-managed persistence capabilities offered by the EJB container.
Using a local or a remote architecture affects the design of the application and its deployment strategy. Figure 11.9 would have fewer layers had it reflected this local client view design. With a local client view, the design can include finer granularity between components. Local method calls do not have the overhead of remote method calls. Because there are few layers and tiers are co-located, it is not necessary to use value objects or business delegates. Value objects are not necessary for entity beans implemented with a local client view.
Deployment is also affected by use of a local or remote architecture. An application implementing a local architecture must be deployed in one unit. Applications with a remote architecture may be deployed as separate units or as one unit. For example, you can deploy the Web tier separate from the EJB tier, or even deploy EJB components separately.


11.4.2 Fulfillment Center Architecture
The order fulfillment center fulfills customer orders and manages the business's financial transactions. Processing starts in this back end of the system when a customer's purchase order is received from the Web site. Processing an order from start to finish may take a few days.
Three modules comprise the fulfillment center--the order process coordinator, administrator, and supplier modules. There are submodules within each module, such as the customer relations submodule. Each module of the fulfillment center can be packaged in a separate EAR file. Packaging modules separately makes it easier to add and change modules. For example, the supplier currently is internal to the system environment, but the design allows the application assembler to easily add other, external suppliers.
Figure 11.10 shows the modules of the order fulfillment center and their relationships to each other.

Figure 11.10 Order Fulfillment Center Architecture
• The order processing module receives the purchase order and verifies the customer's credit status. The order processing module acts as the processing coordinator or workflow manager, and maintains a global view of the entire order processing flow. When it receives an order from the Web site, it assigns it an identifier and stores it in the database. It communicates with the administrator module if an order requires financial verification.
• The administrator module handles any special financial verification or processing, such as for large orders, and obtains credit card approvals.
• A customer relation submodule within the order processing module notifies the customer that the order has been accepted.
• The order processing module passes the order to the supplier.
• The supplier fills as much of the order as it can from inventory. The supplier maintains the inventory data in a database. It also invoices the order processing module for the portion of the order it is filling and ships this amount.
• The order processing module updates its purchase order records based on information from the supplier and the customer relations submodule notifies the customer of order shipments. This process continues until the order is completely filled.
Figure 11.11 shows the flow of work in the order fulfillment center.
Figure 11.11 Fulfillment Center Workflow
How is this implemented in the application software? The order fulfillment center is process-oriented, its process driven by the receipt of an order from the Web site. It typically performs the same sequence of activities for each order, and this process usually lasts for longer than a single session. Single session refers to a client's session, usually an interactive session on the Web site. A single session lasts a few minutes or it can last up to several hours at most. The order fulfillment center's activities, from start to completion, may last several days.
The software implementing the fulfillment center does not use the Model-View-Controller architecture, although it does make use of some of the J2EE design patterns. The fulfillment center uses a number of the J2EE platform technologies, including JMS API, message-driven enterprise beans, JavaMail API, and XML.
The MVC architecture, with its focus on view presentation, is better for GUI-based applications such as the Web site. It is not as well-suited for handling complex process control with potentially extended latency between activities, nor for loosely-coupled communication between participants. The transactional model for the fulfillment center is also quite different than that for the Web site. Web site actions can be rolled back, but recovery is more complex in the fulfillment workflow.
The fulfillment center GUIs are designed following the MVC architecture. In addition, design strategies such as the session facade pattern used in the Web site may apply in the fulfillment center. When a session facade is used in the fulfillment center, it is used selectively and only for coordinating components within a model. A session facade is not designed to coordinate an entire ongoing process such as that of the fulfillment center. A session facade, because it is a session bean, is better for storing state for the duration of a single session. The entire fulfillment process lasts longer than a single session and its state cannot be held in a session bean. Instead, the fulfillment center maintains its state in persistent storage, using entity beans to store and retrieve this state.
This discussion focuses on the architecture of the order processing module, because this module coordinates all the pieces of the fulfillment center application and ensures that customer orders are processed and filled. It uses the JMS API and message-driven beans to accomplish its tasks. Conceptually, the order processing module divides into three pieces:
• A workflow manager coordinates the activities in the fulfillment center. It knows the overall process and the sequence of activity steps.
• Each activity handles its portion of the business logic. For example, one activity notifies the customer of the order status while a different activity prepares invoices for shipped products.
• Transition delegates handle the details of transitioning to the next activity. They prepare messages and send them to JMS destinations.
The order processing module implements a persistent message model that ensures that message state is saved. The order processing module sends messages to JMS destinations, some of which are queues and others are topics. A queue saves message state until the message is received. A topic is used to distribute a message to multiple recipients who have subscribed to the topic. The fulfillment center uses durable topic subscriptions so that message state is saved until all recipients receive the message.
The fulfillment center separates the implementation of process control from business logic. A process manager is responsible for the entire workflow process. It knows the sequence of steps and the rules for following these steps. It ensures that the appropriate module or activity is invoked at the right point to carry out an operation. If necessary, it saves process state in persistent storage so that an order can be filled over multiple days. The process manager uses a persistent message model that saves message state. The activity module contains the business logic, which determines how the operation should be carried out. The business logic within a given activity may be implemented with a session facade pattern.
Messages are sent asynchronously using the JMS API between work flow activities. For example, the manage order flow activity sends an asynchronous message (through a JMS queue) to the verify credit activity so that the customer's credit is verified before completing the order. The verify credit activity sends an asynchronous message to the process manager indicating the results of the credit check. These messages are encoded in XML, making it easy for different applications to communicate. The customer relations submodule uses the JavaMail API to send e-mail notifying customers of order acceptance and shipments.
Each activity in the fulfillment center corresponds to a named JMS destination, either a queue or topic. This named destination is the endpoint that maps to a step in the workflow. Components of the system can send messages to and receive messages from these named destinations. A message-driven bean implements the boundary of the application or module responsible for each piece of the work flow. A message-driven bean enables asynchronous process control messaging, thereby removing any tight-coupling restrictions between activities. The message-driven bean receives and handles the incoming message request to the particular destination. It passes the message contents to its related work activity module, which might be the module to formulate an order addressed to the supplier or a notification message for the customer, and that module carries out the operation. The message-driven bean then invokes a transition delegate, whose responsibility is to notify the next step in the work flow. The order of steps in the work flow is determined and coded appropriately in each transition delegate. The transition delegate asynchronously sends the appropriate message to a named JMS destination, which is subscribed to by the next activity in the sequence. The delegate may also notify the order processing module so that it can maintain its global view of the work flow.
Depending on the particular point in the work flow, a transition delegate may be notifying a single activity or it may be notifying several activities. When it needs to notify a single activity, a transition delegate sends its message to a JMS queue. The message-driven bean for the activity that has subscribed to this queue receives any messages sent to the queue. The queue holds the message until it is received by the message-driven bean. When a transition delegate notifies more than one activity, it sends a message to a JMS topic that is subscribed to by the interested activities. This is a durable subscription to ensure that the topic holds the message until received by all subscribers. For example, the transition delegate for the ship order activity notifies the invoice order activity and the notify customer activity. The invoice order activity and the notify customer activity both subscribe to the same named topic to which the ship order transition delegate sends its message. They both receive the message and can act upon it.
Figure 11.12 shows how the activity workflow manager software models a portion of the process control workflow. The diagram shows the message-driven bean placed at the boundary of each activity to receive messages for that activity and the transition delegate that knows the JMS destination subscribed to by the next activity in the sequence. Messages are encoded in XML and are sent via the JMS API to a JMS destination, either a queue or topic.

Figure 11.12 Process Work Flow of Fulfillment Center
As noted previously, the process work flow often takes longer than a single session to complete. The state of the various activities must be saved. While the process work flow diagram does not show where and when state is saved, entity beans save state when needed to the purchase order or inventory database.
http://java.sun.com/blueprints/guidelines/designing_enterprise_applications_2e/app-arch/app-arch5.html