Front controller
- 4 min read
- 6 chapters
Related on Lably
Through Website, Web application and Java (programming language)
Instruction
Front controllers are often used in web applications to implement workflows. While not strictly required, it is much easier to control navigation across a set of related pages (for instance, multiple pages used in an online purchase) from a front controller than it is to assign individual pages responsibility for navigation.
The front controller may be implemented as a Java object, or as a script in a scripting language such as PHP, Raku, Python or Ruby that is called for every request of a web session. This script would handle all tasks that are common to the application or the framework, such as session handling, caching and input filtering. Based on the specific request, it would then instantiate further objects and call methods to handle the required tasks.
The alternative to a front controller is the usage of page controllers mapped to each site page or path. Although this may cause each individual controller to contain duplicate code, the page-controller approach delivers a high degree of specialization.
Sign in to keep reading
5 more chapters are free with a Lably account.
Examples
Several web-tier application frameworks implement the front controller pattern:
- Apache Struts
- ASP.NET MVC
- Cairngorm framework in Adobe Flex
- Cro or Bailador frameworks in Raku
- Drupal
- MVC frameworks written in PHP, such as Yii, CakePHP, Laravel, Symfony, CodeIgniter and Laminas
- Spring Framework
- Yesod, written in Haskell
Implementation
Front controllers may divided into three components:
- XML mapping: files that map requests to the class that will handle the request processing.
- Request processor: used for request processing and modifying or retrieving the appropriate model.
- Flow manager: determines what will be shown on the next page.
Participants and responsibilities
Java implementation example
The front controller implemented in Java code:
<span id="mwVg"></span><span class="linenos" data-line="1" id="mwVw"></span><span class="kd" id="mwWA">private</span><span class="w" id="mwWQ"> </span><span class="kt" id="mwWg">void</span><span class="w" id="mwWw"> </span><span class="nf" id="mwXA">doProcess</span><span class="p" id="mwXQ">(</span><span class="n" id="mwXg">HttpServletRequest</span><span class="w" id="mwXw"> </span><span class="n" id="mwYA">request</span><span class="p" id="mwYQ">,</span> <span class="linenos" data-line="2" id="mwYg"></span><span class="w" id="mwYw"> </span><span class="n" id="mwZA">HttpServletResponse</span><span class="w" id="mwZQ"> </span><span class="n" id="mwZg">response</span><span class="p" id="mwZw">)</span> <span class="linenos" data-line="3" id="mwaA"></span><span class="w" id="mwaQ"> </span><span class="kd" id="mwag">throws</span><span class="w" id="mwaw"> </span><span class="n" id="mwbA">IOException</span><span class="p" id="mwbQ">,</span><span class="w" id="mwbg"> </span><span class="n" id="mwbw">ServletException</span><span class="w" id="mwcA"> </span><span class="p" id="mwcQ">{</span> <span class="linenos" data-line="4" id="mwcg"></span><span class="w" id="mwcw"> </span><span class="p" id="mwdA">...</span> <span class="linenos" data-line="5" id="mwdQ"></span><span class="w" id="mwdg"> </span><span class="k" id="mwdw">try</span><span class="w" id="mweA"> </span><span class="p" id="mweQ">{</span> <span class="linenos" data-line="6" id="mweg"></span><span class="w" id="mwew"> </span><span class="n" id="mwfA">getRequestProcessor</span><span class="p" id="mwfQ">().</span><span class="na" id="mwfg">processRequest</span><span class="p" id="mwfw">(</span><span class="n" id="mwgA">request</span><span class="p" id="mwgQ">);</span> <span class="linenos" data-line="7" id="mwgg"></span><span class="w" id="mwgw"> </span><span class="n" id="mwhA">getScreenFlowManager</span><span class="p" id="mwhQ">().</span><span class="na" id="mwhg">forwardToNextScreen</span><span class="p" id="mwhw">(</span><span class="n" id="mwiA">request</span><span class="p" id="mwiQ">,</span><span class="w" id="mwig"> </span><span class="n" id="mwiw">response</span><span class="p" id="mwjA">);</span> <span class="linenos" data-line="8" id="mwjQ"></span><span class="w" id="mwjg"> </span><span class="p" id="mwjw">}</span><span class="w" id="mwkA"> </span><span class="k" id="mwkQ">catch</span><span class="w" id="mwkg"> </span><span class="p" id="mwkw">(</span><span class="n" id="mwlA">Throwable</span><span class="w" id="mwlQ"> </span><span class="n" id="mwlg">ex</span><span class="p" id="mwlw">)</span><span class="w" id="mwmA"> </span><span class="p" id="mwmQ">{</span> <span class="linenos" data-line="9" id="mwmg"></span><span class="w" id="mwmw"> </span><span class="n" id="mwnA">String</span><span class="w" id="mwnQ"> </span><span class="n" id="mwng">className</span><span class="w" id="mwnw"> </span><span class="o" id="mwoA">=</span><span class="w" id="mwoQ"> </span><span class="n" id="mwog">ex</span><span class="p" id="mwow">.</span><span class="na" id="mwpA">getClass</span><span class="p" id="mwpQ">().</span><span class="na" id="mwpg">getName</span><span class="p" id="mwpw">();</span> <span class="linenos" data-line="10" id="mwqA"></span><span class="w" id="mwqQ"> </span><span class="n" id="mwqg">nextScreen</span><span class="w" id="mwqw"> </span><span class="o" id="mwrA">=</span><span class="w" id="mwrQ"> </span><span class="n" id="mwrg">getScreenFlowManager</span><span class="p" id="mwrw">().</span><span class="na" id="mwsA">getExceptionScreen</span><span class="p" id="mwsQ">(</span><span class="n" id="mwsg">ex</span><span class="p" id="mwsw">);</span> <span class="linenos" data-line="11" id="mwtA"></span><span class="w" id="mwtQ"> </span><span class="c1" id="mwtg">// Put the exception in the request</span> <span class="linenos" data-line="12" id="mwtw"></span><span class="w" id="mwuA"> </span><span class="n" id="mwuQ">request</span><span class="p" id="mwug">.</span><span class="na" id="mwuw">setAttribute</span><span class="p" id="mwvA">(</span><span class="s" id="mwvQ">"javax.servlet.jsp.jspException"</span><span class="p" id="mwvg">,</span><span class="w" id="mwvw"> </span><span class="n" id="mwwA">ex</span><span class="p" id="mwwQ">);</span> <span class="linenos" data-line="13" id="mwwg"></span><span class="w" id="mwww"> </span><span class="k" id="mwxA">if</span><span class="w" id="mwxQ"> </span><span class="p" id="mwxg">(</span><span class="n" id="mwxw">nextScreen</span><span class="w" id="mwyA"> </span><span class="o" id="mwyQ">==</span><span class="w" id="mwyg"> </span><span class="kc" id="mwyw">null</span><span class="p" id="mwzA">)</span><span class="w" id="mwzQ"> </span><span class="p" id="mwzg">{</span> <span class="linenos" data-line="14" id="mwzw"></span><span class="w" id="mw0A"> </span><span class="c1" id="mw0Q">// Send to general error screen</span> <span class="linenos" data-line="15" id="mw0g"></span><span class="w" id="mw0w"> </span><span class="n" id="mw1A">ex</span><span class="p" id="mw1Q">.</span><span class="na" id="mw1g">printStackTrace</span><span class="p" id="mw1w">();</span> <span class="linenos" data-line="16" id="mw2A"></span><span class="w" id="mw2Q"> </span><span class="k" id="mw2g">throw</span><span class="w" id="mw2w"> </span><span class="k" id="mw3A">new</span><span class="w" id="mw3Q"> </span><span class="n" id="mw3g">ServletException</span><span class="p" id="mw3w">(</span><span class="s" id="mw4A">"MainServlet: unknown exception: "</span><span class="w" id="mw4Q"> </span><span class="o" id="mw4g">+</span> <span class="linenos" data-line="17" id="mw4w"></span><span class="w" id="mw5A"> </span><span class="n" id="mw5Q">className</span><span class="p" id="mw5g">);</span> <span class="linenos" data-line="18" id="mw5w"></span><span class="w" id="mw6A"> </span><span class="p" id="mw6Q">}</span> <span class="linenos" data-line="19" id="mw6g"></span><span class="w" id="mw6w"> </span><span class="p" id="mw7A">}</span>Benefits and liabilities
There are three primary benefits associated with the front controller pattern.
- Centralized control. The front controller handles all the requests to the web application. This implementation of centralized control that avoids using multiple controllers is desirable for enforcing application-wide policies such as user tracking and security.
- Thread safety. A new command object arises when receiving a new request, and the command objects are not meant to be thread-safe. Thus, it will be safe in the command classes. Though safety is not guaranteed when threading issues are gathered, code that interacts with commands is still thread-safe.
- Configurability. As only one front controller is employed in a web application, the application configuration may be greatly simplified. Because the handler shares the responsibility of dispatching, new commands may be added without changes needed to the code.
The front controller pattern may incur performance issues because the single controller is performing a great deal of work, and handlers may introduce bottlenecks if they involve database or document queries. The front controller approach is also more complex than that of page controllers.
Relationship with MVC
- In order to improve system reliability and maintainability, duplicate code should be avoided and centralized when it involves common logic used throughout the system.
- The data for the application is best handled in a single location, obviating the need for duplicate data-retrieval code.
- Different roles in the model-view-controller (MVC) pattern should be separated to increase testability, which is also true for the controller part in the MVC pattern.
Comparison
The page-controller pattern is an alternative to the front controller approach in the MVC model.

