Many interactive Web applications are composed of brittle collections of interdependent Web pages. Such applications can be hard to maintain and extend.
The Front Controller pattern defines a single component that is responsible for processing application requests. A front controller centralizes functions such as view selection, security, and templating, and applies them consistently across all pages or views. Consequently, when the behavior of these functions need to change, only a small part of the application needs to be changed: the controller and its helper classes.
Core J2EETM
Patterns
A Servlet is utilized as the main point of entry for web requests. The class
MainServlet
is the front controller for the Java Pet Store sample application
website. All requests that end with *.do are mapped to go through
the MainServlet for processing. The following code excerpts form
the core of the controller. A sequence diagram outlining the actions
taken by the
MainServlet in response to the user request appears in
Figure 1 below.
|
| Figure 1. Sequence diagram of MainServlet in action |
The
MainServlet source code is straightforward:
doProcess, shown in this example. The
method receives the request and response, and passes the
request to the
RequestProcessor,
which dispatches the request to
the business logic (represented by the "Model" in
Figure 1 above) that handles it. The request processor
executes an application function that corresponds to the
request URL ("2: dispatch" in Figure 1). The map from request URLs to application
functions is
defined in an XML file,
mappings.xml.
private void doProcess(HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException {
...
try {
getRequestProcessor().processRequest(request);
ScreenFlowManager,
which chooses the next screen
to display, again based on the contents of
mappings.xml ("3: select view" in Figure 1).
Exceptions can also be mapped
to screens in
mappings.xml: if business logic
throws an exception, the exception is stored in the
request, and the next screen is chosen based on the
exception type. If no next screen is defined, a default screen
is used.
getScreenFlowManager().forwardToNextScreen(request, response);
} catch (Throwable ex) {
String className = ex.getClass().getName();
nextScreen = getScreenFlowManager().getExceptionScreen(ex);
// put the exception in the request
request.setAttribute("javax.servlet.jsp.jspException", ex);
if (nextScreen == null) {
// send to general error screen
ex.printStackTrace();
throw new ServletException("MainServlet: unknown exception: " +
className);
}
}
ScreenFlowManager, which forwards to the next screen.