Application Controller Design Pattern in Java

Use an Application Controller to centralize retrieval and invocation of request-processing components, such as commands and views.
Let's discuss how Application Controller Design Pattern works with examples.
This pattern is divided into a number of sections for simplicity like problem, forces, structure, solution, implementation etc.
Table of contents
Problem
Forces
Solution
Explanation
Structure - Class Diagram, Sequence Diagram
Participants and Responsibilities
Implementation
Consequences
Applicability
Real world examples
References

Problem

(Problem section describes the design issues faced by the developer)
You want to centralize and modularize action and view management.
In the presentation tier, there are typically two decisions to be made upon the arrival of each request:
  • First, the incoming request must be resolved to an action that services the request. This is called action management.
  • Second, the appropriate view is located and dispatched. This is called view management.

Forces

  • You want to reuse action and view-management code.
  • You want to improve request-handling extensibility, such as adding use case functionality to an application incrementally.
  • You want to improve code modularity and maintainability, making it easier to extend the application and easier to test discrete parts of your request-handling code independent of a web container.

Solution

Use an Application Controller to centralize retrieval and invocation of request-processing components, such as commands and views.
In the presentation tier, we map incoming request parameters to specific request-processing classes, and to view components that handle each request.  
Action management refers to locating and invoking actions to handle specific requests, while view management refers to navigating and dispatching to the appropriate view or view-generation mechanism.

Structure

Let's use UML class diagram to represent the basic structure of the solution and the UML Sequence diagram in this section present the dynamic mechanisms of the solution. 
Below is the class diagram representing the relationships for the Application Controller pattern.

Class Diagram

Sequence Diagram

Participants and Responsibilities

Client: Invokes the Application Controller. In the presentation tier, a FrontController or an InterceptingFilter typically fulfill this role.
ApplicationController : Uses Mapper to resolve an incoming request to the appropriate action and view, to which it delegates or dispatches.
Mapper : Uses a Map to translate an incoming request into the appropriate action and view. A Mapper acts as a factory.
Map: Holds references to handles that represent target resources. Maps might be realized as a class or a registry.
Target : A resource that helps fulfill a particular request, including commands, views, and style sheets.

Implementation

Let's understand Application Controller Pattern with an example.
Step 1: Let's create view components like index.jsp and viewStudent.jsp pages.
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
 <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">

 <title>Index Page</title>
</head>
<body>
 <a href="studentView.do?id=10">Show Student Information</a>
</body>
</html>

<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<jsp:useBean id="student" type="design.StudentVO" scope="request" />
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
 <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
 <title>Student Information</title>
</head>
<body>
 <p style="color: blue;font-size:x-large; large;font-family: sans-serif;">
 Student Id : <jsp:getProperty property="id" name="student"/><br>
 Student Name : <jsp:getProperty property="name" name="student"/>
 </p>
</body>
</html>
Step 2: Application Controller Pattern is J2EE Design Pattern so let's create deployment descriptor that is web.xml.
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   
xmlns="http://java.sun.com/xml/ns/javaee"   
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee   
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"   
id="WebApp_ID" version="3.0">  

 <display-name>ApplicationControllerWeb</display-name>
 <servlet>
   <servlet-name>front</servlet-name>
   <servlet-class>design.FrontController</servlet-class>
 </servlet>
 <servlet-mapping>
   <servlet-name>front</servlet-name>
   <url-pattern>*.do</url-pattern>
 </servlet-mapping>

 <welcome-file-list>
  <welcome-file>index.jsp</welcome-file>
 </welcome-file-list>
 
</web-app>
Step 3: Let's create Value Object Or DTO like StudentVO.java.
public class StudentVO {
    private String id;
    private String name;

    //constructor
    public StudentVO(String id, String name) {
        this.id = id;
        this.name = name;
    }

    //setters and getters

    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}
Now create Command interface.
public interface Command {
    String execute(RequestContext requestContext);
}
StudentViewCommand class which implements Command interface
public class StudentViewCommand implements Command {

    @Override
    public String execute(RequestContext requestContext) {

        String id = null;
        StudentVO studentVo = null;

        id = requestContext.getParameter("id");

        //call delegate and dao 
        studentVo = new StudentVO(id, "Ramesh");

        requestContext.setAttribute("student", studentVo);

        return "showStudent";
    }

}
Create ContextFactory to handle context information.
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

public class ContextFactory {

    public RequestContext getContextObject(HttpServletRequest request) {
        Map < String, String[] > requestMap = null;
        RequestContext requestContext = null;
        HttpRequestMapper requestMapper = null;

        requestMapper = new HttpRequestMapper();
        requestMap = requestMapper.extract(request);
        requestContext = new RequestContext(request.getRequestURI(), requestMap);

        return requestContext;
    }

    public void bindContextObject(HttpServletRequest request, RequestContext requestContext) {
        HttpRequestMapper requestMapper = null;

        requestMapper = new HttpRequestMapper();
        requestMapper.bind(request, requestContext.getResponseMap());
    }

}
Let's create RequestContext class.
import java.util.HashMap;
import java.util.Map;

public class RequestContext {

    private String requestUri;
    private Map < String, String[] > requestMap;
    private Map < String, Object > responseMap;

    public RequestContext() {
        requestUri = null;
        requestMap = new HashMap < String, String[] > ();
        responseMap = new HashMap < String, Object > ();
    }

    public RequestContext(String requestUri, Map < String, String[] > requestMap) {
        this.requestUri = requestUri;
        this.requestMap = requestMap;
        this.responseMap = new HashMap < String, Object > ();
    }

    public String getParameter(String param) {
        String[] val = null;
        if (param != null) {
            val = requestMap.get(param);
        }
        return val[0];
    }

    public void setAttribute(String param, Object value) {
        responseMap.put(param, value);
    }

    public String getRequestUri() {
        return requestUri;
    }

    public Map < String, String[] > getRequestMap() {
        return requestMap;
    }

    public Map < String, Object > getResponseMap() {
        return responseMap;
    }

}
Step 4: It's time to create FrontController.java.
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class FrontController extends HttpServlet {

    private static final long serialVersionUID = 1 L;

    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {

        String page = null;
        String view = null;
        Dispatcher dispatcher = null;
        RequestContext requestContext = null;
        ContextFactory contextFactory = null;
        ApplicationController applicationController = null;

        // plubbing code (security, authorization)

        // extracting data from protocol
        contextFactory = new ContextFactory();
        requestContext = contextFactory.getContextObject(request);

        applicationController = new ApplicationController();
        view = applicationController.process(requestContext);

        // binding data back to protocol
        contextFactory.bindContextObject(request, requestContext);
        page = applicationController.mapViewToPage(view);

        dispatcher = new Dispatcher();
        dispatcher.dispatch(request, response, page);
    }
}
Step 5 : Create ApplicationController class and respective classes required to demonstrate this pattern.
public class ApplicationController {

    public String process(RequestContext requestContext) {
        String view = null;
        Command command = null;
        CommandHelper commandHelper = null;

        commandHelper = new CommandHelper();
        command = commandHelper.getCommand(requestContext.getRequestUri());
        view = command.execute(requestContext);

        return view;
    }

    public String mapViewToPage(String view) {
        String page = null;
        if (view != null) {
            page = "viewStudent.jsp";
        }

        return page;
    }
}
public class CommandHelper {

    public Command getCommand(String uri) {

        Command command = null;
        if (uri.contains("studentView.do")) {
            command = new StudentViewCommand();
        }

        return command;
    }

}
public class Dispatcher {

    public void dispatch(HttpServletRequest request, HttpServletResponse response, String page) {

        RequestDispatcher rd = null;

        rd = request.getRequestDispatcher(page);
        try {
            rd.forward(request, response);
        } catch (ServletException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;

public class HttpRequestMapper {

    public Map < String, String[] > extract(HttpServletRequest request) {
        Map < String, String[] > requestMap = null;
        requestMap = request.getParameterMap();

        return requestMap;
    }

    public void bind(HttpServletRequest request, Map < String, Object > responseMap) {

        Set < String > keys = null;
        keys = responseMap.keySet();

        for (String param: keys) {
            request.setAttribute(param, responseMap.get(param));
        }

    }

}
Output :
http://localhost:8001/javaT/

http://localhost:8001/javaT/studentView.do?id=10

browser :
Student Id : 100
Student Name : Ramesh

Consequences

  • Improves modularity
  • Improves reusability
  • Improves extensibility

References

Related Presentation Tier Posts

Free Spring Boot Tutorial | Full In-depth Course | Learn Spring Boot in 10 Hours


Watch this course on YouTube at Spring Boot Tutorial | Fee 10 Hours Full Course

Comments

  1. Really this article is truly one of the best in article history and am a collector of old "items" and sometimes read new items if i find them interesting which is one that I found quite fascinating and should be part of my collection. Very good work!
    Data Scientist Course in Gurgaon

    ReplyDelete
  2. Nice post. This is a great article and am pretty much pleased with your good work. Very helpful information. Thank you.
    Best Data Science Courses

    ReplyDelete
  3. Very informative Blog! There is so much information here that can help thank you for sharing.
    Data Analytics Course in Bangalore

    ReplyDelete
  4. Interesting post. which i wondered about this issue so thanks for posting and very good article which is a really very nice and useful article. Thank you
    Data Science Course in Noida

    ReplyDelete
  5. Very great post which I really enjoy reading this and it is not everyday that I have the possibility to see something like this. Thank You.
    Best Online Data Science Courses

    ReplyDelete
  6. Very interesting blog and lot of the blogs we see these days don't provide anything that interests me but i am really interested in this one just thought I would post and let you know.
    Data Science Training Institute in Noida

    ReplyDelete
  7. Nice Post i have read this article and if I can I would like to suggest some cool tips or advice and perhaps you could write future articles that reference this article. I want to know more!
    Data Analytics Course in Gurgaon

    ReplyDelete
  8. Well done for this excellent article. and really enjoyed reading this article today it might be one of the best articles I have read so far and please keep this work of the same quality.
    Data Analytics Course in Noida

    ReplyDelete
  9. Excellent work done by you once again here and this is just the reason why I’ve always liked your work with amazing writing skills and you display them in every article. Keep it going!
    Data Analytics Courses in Hyderabad

    ReplyDelete
  10. I like viewing this web page which comprehend the price of delivering the excellent useful resource free of charge and truly adored reading your posting. Thank you!
    Data Science Certification Course

    ReplyDelete
  11. Just a shine from you here and have never expected anything less from you and have not disappointed me at all which i guess you will continue the quality work. Great post.
    Data Science Training in Gurgaon

    ReplyDelete
  12. Thanks for sharing this valuable information,we provide pinterest video download which helps to get more ideas to write more quality content.

    ReplyDelete
  13. Thank you for sharing this wonderful blog, I read that Post and got it fine and informative. Please share more like that...
    Business Analytics Course in Amritsar

    ReplyDelete

Post a Comment