Front Controller Design Pattern Tutorials with Examples
The Front Controller is a crucial design pattern extensively used in web applications, serving as a singular controller to manage all requests within an application.
Front controllers find prominent usage in MVC applications and are commonly implemented in various frameworks, including:
- Legacy Java web apps
- Struts
- Spring Boot and MVC
- Angular, React, and Vue.js frameworks
- Microsoft .NET and SharePoint
Why is the Front Controller Pattern Required?
Let’s look into the reasons behind the necessity of the Front Controller and the issues it resolves.
In a web application, when clients send requests to the server, the server processes the request, potentially makes database calls, retrieves data from the database or other third-party systems, processes the data, and sends back a response.
This involves different components:
- Business data validation
- Holding the database data (model)
- View processing
Due to this process, there is a lack of a single point of contact for the request. The Front Controller design pattern addresses this issue.
In Java web applications, Servlets serve as controllers positioned in front of other resources. In this pattern, Servlets act as a single central entry point for requests sent by browsers, mobile clients, and standalone apps, delegating the requests to the appropriate web resources.
For instance, ActionServlet
is the front controller for Struts-based applications, and DispatchServlet
serves as the front controller for Spring Web MVC-based applications.
Front Controller Design Pattern Example
Consider a simple example illustrating how requests from both mobile and desktop clients are processed via a single controller.
Let’s define Java classes.
DesktopClient
represents a client sending a request from a desktop.
public class DesktopClient {
public void render() {
System.out.println("Desktop UI rendered");
}
}
MobileClient
represents a client sending a request from a mobile device.
public class MobileClient {
public void render() {
System.out.println("Mobile UI rendered");
}
}
In real-time scenarios, these are requests from an Android app for MobileClient
and a browser request for DesktopClient
.
Next, create a simple DispatchHandler
class responsible for delegating requests based on the request type.
if the request is from mobile, Delegate the request to mobile rendering logic else Delegate request to desktop rendering logic.
public class DispatchHandler {
private final MobileClient mobile;
private final DesktopClient desktop;
public DispatchHandler() {
mobile = new MobileClient();
desktop = new DesktopClient();
}
public void dispatchRequest(String request) {
if (request.equalsIgnoreCase("mobile")) {
mobile.render();
} else {
desktop.render();
}
}
}
FrontController.java
contains the central logic for calling the handler, optional logic to add filters to the request, and logic for authorization
and authentication
. The main method demonstrates sending requests from both mobile and desktop.
public class FrontController {
private final DispatchHandler handler;
public FrontController() {
handler = new DispatchHandler();
}
public static void main(String[] args) {
FrontController fc = new FrontController();
fc.handler.dispatchRequest("mobile"); // request is from mobile
fc.handler.dispatchRequest("desktop"); //request is from desktop or tablet
}
}
Output
Movile UI rendered
Desktop UI rendered
Advantages
- Centralized code logic for the controller
- Loose coupling with different components, as validations and delegations are separated
- Easy-to-write logic and focus
- Thread safety can be achieved by writing logic
- Sinle point of contact for incoming processing request,returning response