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