Sun Java Solaris Communities My SDN Account Join SDN
 
J2EE

Sun Java Center J2EE Patterns

 

Front Controller

Context

System handles web requests. Presentation processing requires complex view navigation, creation and delivery.

Problem

The system requires a centralized access point for presentation request handling to support the integration of system services, content retrieval, view management, and navigation. When the user accesses the view directly without going through a centralized mechanism two problems may occur:

  • Each view is required to provide its own system services, often resulting in duplicate code.
  • View navigation is left to the views which may result in commingled view content and view navigation.

Forces

  • Common system services processing completes per request. For example, the security service completes authentication and authorization checks.
  • Logic that is best handled in one central location instead is replicated within numerous Views.
  • Decision points exist with respect to the retrieval and manipulation of data.
  • Multiple views are used to respond to similar business requests.
  • A centralized point of contact for handling a request may be useful, for example to control and log a user's progress through the site.
  • System services and view management logic are relatively sophisticated.

Solution

Use a Controller as the initial point of contact for handling a request. The Controller manages the handling of the request, including invoking security services such as authentication and authorization, delegating business processing, managing the choice of an appropriate view, handling errors, and managing the selection of content creation strategies.

The Controller provides a centralized entry point that controls and manages web request handling. By centralizing decision points and controls, the Controller also helps reduce the amount of Java code, called scriptlets, embedded in the JSPTM.

Centralizing control in the Controller and reducing business logic in the view promotes code reuse across requests. It is a preferable approach to the alternative-embedding code in multiple views-because that approach may lead to a more error-prone, reuse-by-copy-and-paste environment.

Typically, a Controller works in coordination with a Dispatcher component. A Dispatcher is responsible for view management and navigation. Thus, a Dispatcher manages choosing the next View to present to the user and provides the mechanism for vectoring control to this resource. A Dispatcher can be encapsulated within a Controller or can be a separate component (see ServiceToWorker pattern).

The FrontController pattern suggests centralizing handling of requests, but does not limit the number of handlers in the system. There may very well be multiple Front Controllers in a system with each mapping to a set of distinct services.

Structure

The following class diagram represents the FrontController pattern:

 

Participants & Responsibilities

The following sequence diagram represents the FrontController pattern. It depicts how the FrontController handles a request.

Controller

The FrontController is the initial contact point for handling all requests in the system. The FrontController typically interacts with the Dispatcher (when used in conjunction with Service To Worker).

The Front Controller may delegate to a Helper to complete authentication and authorization of a user, or to initiate content retrieval.

Dispatcher

A Dispatcher is responsible for view management and navigation, managing the choice of the next View to present to the user and providing the mechanism for vectoring control to this resource.

A Dispatcher can be encapsulated within a Controller or can be a separate component working in coordination. The Dispatcher can provide static dispatching to the View or may provide a more sophisticated dynamic dispatching mechanism.

The Dispatcher will use the RequestDispatcher object (supported in the Servlet specification) and will encapsulate some additional processing.

Helper

A Helper is responsible for helping a View or Controller complete its processing. Thus, Helpers have numerous responsibilities, including gathering data required by the View and adapting [See GoF Adaptor pattern] this data model for use by the View. Helpers can service requests for data from the View by simply providing access to the raw data or by formatting the data as web content.

A View may work with any number of Helpers, which are typically implemented as JavaBeansTM (JSPTM 1.0) and Custom Tags (JSP 1.1+). Additionally, a Helper may represent a Command object, a Delegate (see Business Delegate pattern), or an XSL Transformer, which is used in combination with a stylesheet to adapt and convert the model into the appropriate form.

View

A View represents and displays information to the client. The information that is used in a display is retrieved from a model. Helpers support Views by encapsulating and adapting a model for use in a display.

 

Strategies

There are several strategies relating to Controller implementation.

 

ServletFront Strategy

This strategy suggests implementing the Front Component as a Servlet. Though semantically equivalent, it is preferred to the 'JSPFront Strategy'. The Front Component handles request processing, managing and controlling aspects of this processing. Since these responsibilities are related to, but logically independent of display formatting, they are more appropriately included in a Servlet instead of a JSP.

The ServletFront Strategy does have some potential drawbacks. In particular, it does not leverage some of the JSP runtime environment utilities, such as automatic population of request parameters into Helper properties. Fortunately, this drawback is minimal because it is relatively easy to create or obtain similar utilities for general use. There is also the possibility that the functionality of some of the JSP utilities may be included as standard Servlet features a future version of the Servlet specification. 

 
JSPFront Strategy

This strategy suggests implementing the Front Component as a JSP. Though semantically equivalent, the 'ServletFront Strategy' is preferred to the 'JSPFront Strategy'. Since the Front Component handles processing that is not specifically related to display formatting, it is a mismatch to implement this component as a JSP.

Implementing the Front Component as a JSP is clearly not preferred for another reason: It requires a software developer to work with a page of markup in order to modify request handling logic. Thus, a software developer will typically find the 'JSPFront strategy' more cumbersome when completing the cycle of coding, compilation, testing, and debugging. 

 

Command and Controller Strategy

Based on the Command pattern [GoF], the Command and Controller Strategy suggests providing a generic interface to the helper components to which the controller may delegate responsibility, minimizing the coupling among these components (See the ViewHelper pattern for more information on Helper components). Adding to or changing the work that needs to be completed by these helpers does not require any changes to the interface between the controller and the helpers, but rather to the type and/or content of the commands. This provides a flexible and easily extensible mechanism for developers to add request handling behaviors.

Finally, because the command processing is not coupled to the command invocation, the command processing mechanism may be reused with various types of clients, not just web browsers. This strategy also facilitates the creation of composite commands (see Composite Pattern [GoF]).

 

Physical Resource Mapping Strategy

All requests are made to specific physical resource names rather than logical names. An example is the following URL:

http://some.server.com/resource1.jsp

In the case of a controller, an example URL might be:

http://some.server.com/servlet/Controller

The 'Logical Resource Mapping Strategy' is typically preferred over this strategy, since it provides much greater flexibility. Resource mappings are modified in a declarative manner, via a configuration file, instead of making changes to each resource, which is necessary when implementing this strategy.

 

Logical Resource Mapping Strategy

Requests are made to logical resource names rather than to specific physical names. The physical resources to which these logical names refer may then be modified in a declarative manner. For example, the URL:

http://some.server.com/process

may be mapped as follows: process = resource1.jsp OR process = resource2.jsp OR process = servletController.

 

Multiplexed Resource Mapping Strategy

This is actually a sub-strategy of 'Logical Resource Naming Strategy'. Not only is a single logical name mapped to a single physical resource, a whole set of logical names are mapped to a single physical resource. For example, a wildcard mapping might map all requests that end with .ctrl to a specific handler.

A request and mapping might look as follows:

Request

Mapping

http://some.server.com/action.ctrl

*.ctrl = servletController

In fact, this is the strategy JSP engines use in order to ensure that requests for JSP resources (for example, resources whose names end in .jsp) are processed by a specific handler.

Additional information can also be added to a request, providing further details to leverage for this logical mapping. For example:

Request

Mapping

http://some.server.com/profile.ctrl?usecase=create

*.ctrl = servletController

A key benefit of using this strategy is that it provides great flexibility when designing your request handling components. When combined with other strategies, such as the 'Command and Controller Strategy', one can create a powerful request handling framework.

Consider a controller that handles all requests ending in .ctrl, as described above. Also, consider the left side of this dot-delimited resource name ('profile' in the above example) to be one part of the name of a use case. Now combine this name with the query parameter value ('create' in the above example). We are signaling our request handler that we want to process a use case called 'create profile'. Our multiplexed resource mapping sends the request to our servletController. Our controller creates the appropriate command object, as described in the 'Command and Controller Strategy'. How does the controller know what command object to which it should delegate? Leveraging the additional information in the request URI, the controller delegates to the command object that handles profile creation. This might be a ProfileCommand object that services requests for Profile creation and modification, or it might be a more specific ProfileCreationCommand object.

Dispatcher in Controller Strategy

When the Dispatcher functionality is minimal, it can be folded into the Controller, as shown in the following sequence diagram.

BaseFront Strategy

Used in combination with the ServletFront Strategy, this strategy suggests implementing a Controller base class, whose implementation other Controllers may extend. The base front may contain common and default implementations, while each subclass can override these implementations. The drawback of this strategy is the fact that any shared superclass, while promoting reuse and sharing, raises the issue of creating a fragile hierarchy, where changes necessary for one subclass affect all subclasses.

 

Consequences

  • Centralized Control
    This strategy provides a central place to handle system services and business logic across multiple requests. Because some decisions (such as the JSP to which the request should be sent) can only be made after the completion of certain business logic, it is important that the decision-making process occur in a centralized place. The controller can manage business logic processing and request handling, and can make its decisions utilizing retrieved or calculated values that are based on the business calls. Keep in mind, though, that as control centralizes, it is possible to introduce a single point of failure.
  • Security
    Centralized security control based on, for example, defined user roles is possible in the Controller.
  • Improved Reusability
    Promotes cleaner application partitioning and encourages reuse. Code that is common among components is moved into the front controller and reused for each request.
  • User Tracking and Logging
    Allows the tracking of a particular user and logging of related activity.
  • Validation and Error Handling
    The controller can also manage validation and error handling, because these operations are often done per request.

 

Related Patterns

  • View Helper Pattern [SJC]
    The Front Controller is combined with the View Helper pattern to provide containers for factoring business logic out of the View and to provide a central point of control and dispatch. Logic is factored forward into the front controller and back into the Helpers.
  • Service to Worker [SJC]
    The Service to Worker pattern is the result of combining the View Helper Pattern with a Dispatcher, in coordination with the Front Controller pattern.
  • Dispatcher View [SJC]
    The Dispatcher View pattern is the result of combining the View Helper Pattern with a Dispatcher, in coordination with the Front Controller pattern.

(c) 2000-2001 Sun Microsystems, Inc. All Rights Reserved.

Version 1.0 Beta