IT Computer Training Articles Tutorials - Submit Your Article - Articles Submission Directory. - http://www.articles.webtechvision.com
J2EE Design Patterns: The Presentation Layer Patterns: Model-View-Controller
http://www.articles.webtechvision.com/articles/21/1/J2EE-Design-Patterns-The-Presentation-Layer-Patterns-Model-View-Controller/Page1.html
Samee Jhor
 
By Samee Jhor
Published on 01/3/2007
 
In any application, it is the presentation that matters most to the end user. The usability of software depends heavily on the User Interface or Presentation Layer in the case of J2EE. Since it is the Presentation Layer that presents the UI to the user, the solutions for recurring problems have to be standard. That is where Presentation Layer Design Patterns come into the picture.

J2EE Design Patterns: The Presentation Layer Patterns: Model-View-Controller

One of the major concerns with the web applications is the separation between the logics that deal with Presentation itself, the data to be presented and the one that controls flow of logic. It is as an answer to such concerns that the Model-View-Controller or MVC pattern was designed. In this discussion I will be concentrating on MVC. The first section will discuss and define MVC. The second section will cover the types of MVC patterns that could be implemented. In the last two sections I will implement both types of patterns within an example. That's the agenda for this discussion.

MVC: What is it?

Though the Model-View-Controller is considered a single Pattern, it consists of three different components. This is due to the nature of the Server-Side Presentation Layer. This layer takes care of not only the UI but also of the state of the application (in other words the data currently displayed as state is represented by the value contained in the attributes of an object). It also handles the processing of user data along with the flow of control. Hence the problem of the Presentation Layer is broken up into three distinct pieces or components: the Model (M), the View (V), and the Controller (C)

Among the three, the Controller sits at the boundary. Hence, it can be considered the one that orchestrates the flow of data between View and Model. Here are the details.

The Model

The Model, represented by the character M, stores the application state. To rephrase it, the data extracted from the business logic layer which has to be presented to the user, and after processing passed back to the business logic layer, is contained within the Model. The data can be represented in any form - JavaBeans, files, Network or even memory.

The main task of Model is to provide access to this data. The access is provided as an abstraction of data. To cut a long story short, the Model object represents the Domain data which needs to be used by the Server-Side Presentation Layer.

Typically JavaBeans are used to implement the Model object because JavaBeans easily can represent any type of data store, be it Tables, files etc. For example, if the data to be presented is coming from the Employee table, then the Model implemented with JavaBeans would be a class containing the Columns of the Table as properties of the class. These properties can be access via getters and setters. Each row of the table would be represented by an object of the JavaBeans class. The state of the class would provide data required by the Server-Side Presentation Layer.

The View

The View, represented by V, accesses data from the Model and generates the corresponding User Interface (UI). By itself, the View is stateless i.e. it can't preserve/remember the data for which the UI was generated. Hence it depends on Model for the same.

The main job of the View component is to generate the UI for the data in the format that would be useful for the client. A single Model can have multiple Views. That means different users may require different formats for the same data. For this to be achieved, multiple Views can be registered with the Model. In J2EE, the View is typically implemented using JSP and Custom Tags to format the data. For example, the Employee data may be viewed by the manager according to the work hours per day, while the accountant may want to see the data according to the basic salary of the employees. To provide for this, different Views can be generated using the combination of JSP and custom tags.

The Controller

As stated earlier, the Controller, the C of MVC, sits at the boundary of the application, intercepting each request. Hence, it can be thought of as the point of first contact for any request. It performs the following tasks:

  • Coordinating the client requests.
  • Updating the Model and Views on the basis of user input.
  • Supervising and planning what needs to be shown and changes to be made.
  • Calling the chosen Model and executing the embedded logic.

For example, while updating an employee's data, once the data has been updated, which page has to be shown would be decided by the Controller.

To present the components and their jobs pictorially, the diagram would look like this:

     

From the above diagram it is clear that there is a one-to-many correspondence between the Controller and the View. Inversely the View has a many-to-one correspondence with the Controller. That covers the pieces of MVC. Next let's look at the types of MVC. 


J2EE Design Patterns: The Presentation Layer Patterns: Model-View-Controller - MVC: the Types

MVC can be implemented in two different ways which constitute the types of MVC. In technical terms the types are known as Models. Please do not confuse this Model with the Model (M) of MVC. Models of MVC represent the ways in which the MVC can be implemented whereas the Model represents data. On the basis of the different ways they are implemented, the two Models are MVC Model-I and MVC Model-II. The point of difference between them is where Controller is implemented. 

MVC Model-I

This Model is also known as the Page Centric Model. In this type of implementation, the View and the Controller exist as one entity -- the View-Controller. In terms of implementation, in the Page Centric approach the Controller logic is implemented within the View i.e. with J2EE, it is JSP. All the tasks of the Controller, such as extracting HTTP request parameters, call the business logic (implemented in JavaBeans, if not directly in the JSP), and handling of the HTTP session is embedded within JSP using scriptlets and JSP action tags. For example, to redirect to another page in the case of an invalid session, the MVC Model-I approach would be the following snippet within the JSP page:

<%

     if(session.getAttribute("USER_ID")==null)

       {

%>

    <jsp:forward page="/authenticator/login.jsp"/>

<%

   //other logic

%>

  Pictorially the MVC Model-I would be:

 

MVC Model-II

The problem with Model-I is its lack of maintainability. With Controller logic embedded within the JSP using scriptlets, the code can get out of hand very easily. So to overcome the problems of maintainability and reusability, the Controller logic can be moved into a servlet and the JSP can be used for what it is meant to be -- the View component. Hence, by embedding Controller logic within a servlet, the MVC Model-II Design Pattern can be implemented.

Thus the major difference between Model-I and Model-II is where the Controller logic is embedded, in JSP or in a servlet. To clarify Model-II a bit more, let's take the example used for Model-I and convert it to Model-II. Instead of embedding the code snippet in JSP, it would become a part of the servlet with necessary modifications as below:

if(session.getAttribute("USER_ID")==null) {

           

            RequestDispatcher dispatcher=request.getRequestDispatcher
("/authenticator/login.jsp");

            dispactcher.forward(request,response);

        }

        else {

      //other logic

}

     Pictorially the MVC Model-II would be:

   

That completes the second section of this discussion. In the next part I will be developing a mailing list application containing both Model-I and Model-II of MVC.


J2EE Design Patterns: The Presentation Layer Patterns: Model-View-Controller - MVC in the Real World

The application to be developed will have the following features:

  • First the user enters his or her first name, last name, and email address into a form which will be added to the list and reports whether the submission was successful.
  • If the submission was successful, the success page will be shown, or else the user will be redirected to the first page.

The following are the files that will be used:

  1. subscribe.html -- provides the interface to enter user data.
  2. MailingBean.java -- a bean functioning as the Model.
  3. ListController.java -- the servlet that will be the Controller.
  4. redirect.jsp -- the View component that contains a part of the Controller logic.

So first comes subscribe.html. It's a simple HTML file. It calls the Controller servlet.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01
Transitional//EN">

<HTML>

  <HEAD>

    <TITLE>Subscribe!</TITLE>

  </HEAD>

  <BODY>

    <FORM action="/servlets/ListController" method="get">

        First Name: <INPUT type="text" name="first"> <br>

        Last Name: <INPUT type="text" name="last"> <br>

        Email Address: <INPUT type="text" name="email"> <br>

        <INPUT type="submit" name="Subscribe!">

    </FORM>

  </BODY>

</HTML>

Next is the Model. Since Models will be discussed in detail in coming parts, the actual implementation is left out for the present. It is an interface. Why it has been kept as an interface and how to implement it will be discussed in the future. It uses getters to retrieve the value and setters to place the value within the bean.

public interface MailingBean {

    // first name

    public String getFirst(  );

    public void setFirst(String first);

    // last name

    public String getLast(  );

    public void setLast(String last);

    // email address

    public String getEmail(  );

    public void setEmail(String email);

    // business method

    public boolean doSubscribe(  );

    // subscription result

    public String getErrorString(  );

}


J2EE Design Patterns: The Presentation Layer Patterns: Model-View-Controller - MVC in the Real World

Now comes the Controller which is implemented as a servlet. It creates an instance of the MailingBean, sets the data, and calls the method for persisting the data. If the call is successful, it sets an attribute in the request scope specifying that the operation is successful; otherwise the attribute specifies that the operation is a failure. Then the request is redirected to the View.

import javax.servlet.*;

import javax.servlet.http.*;

import java.io.IOException;

public class ListController extends HttpServlet {

    public static final String FIRST_PARAM = "first";

    public static final String LAST_PARAM = "last";

    public static final String EMAIL_PARAM = "email";

    public static final String MAILINGBEAN_ATTR = "mailingbean";

    public void init(ServletConfig config)

    throws ServletException {

        super.init(config);

    }

    public void destroy(  ) {

    }

    // handle get requests   

    protected void doGet(HttpServletRequest request,

                         HttpServletResponse response)

    throws ServletException, IOException {

        // read the parameters from the request

        String first = request.getParameter(FIRST_PARAM);

        String last = request.getParameter(LAST_PARAM);

        String email = request.getParameter(EMAIL_PARAM);

        // get the mailing list bean for this list

        MailingBean mb = MailingBeanFactory.newInstance(  );

        // set the parameters into the bean

        mb.setFirst(first);

        mb.setLast(last);

        mb.setEmail(email);

        // perform the business method

        boolean result = mb.doSubscribe(  );

        // choose a page based on the result

        String op = "success";

        if (!result) op = "failure";

       

        String nextPage="/redirect.jsp";

        // store the operation state in the request context

        request.setAttribute(MAILINGBEAN_ATTR, op);

        RequestDispatcher dispatcher =

           getServletContext(  ).getRequestDispatcher(nextPage);

        dispatcher.forward(request, response);       

    }

}

Next comes the JSP. It checks the attribute and redirects accordingly. Here the Controller functionality has been divided into a servlet as well as the following JSP:

<%@page contentType="text/html"%>

<jsp:useBean id="mailingbean" scope="request"

             class="MailingBean" />

<html>

<head><title>Subscription Results</title></head>

<body>

<br><br>

<% if   

    ((String)request.getAttribute
(MAILINGBEAN_ATTR).equalsIgnoreCase

              ("success"))

<%{%>

<jsp:forward page="/success.jsp"/>

<%}

else

{

%>

<jsp:forward page="/failure.jsp"/>

<%

}

%>

</body>

</html>

Here is the success.jsp:

<%@page contentType="text/html"%>

<jsp:useBean id="mailingbean" scope="request"

             class="MailingBean" />

<html>

<head><title>Subscription Results</title></head>

<body>

<br><br>

Dear <jsp:getProperty name="mailingbean" property="first"/>,

<br><br>

Congrats, the address

<jsp:getProperty name="mailingbean" property="email"/>

Has been added to the list.<br><br>

</body>

</html>

And here is the failure.jsp:

<%@page contentType="text/html"%>
<jsp:useBean id="mailingbean" scope="request" 
             class="MailingBean" />
<html>
<head><title>Subscription Results</title></head>
<body>
<br><br>
Dear <jsp:getProperty name="mailingbean" property="first"/>,
<br><br>
We're sorry, the address
<jsp:getProperty name="mailingbean" property="email"/>
could not be added to the list.<br><br>
The problem was: 
<jsp:getProperty name="mailingbean" property="errorString"/>.
</body>

</html>

That completes the application. Though MVC  provides maintainable code, there are still situations in which MVC has limitations. These cases and their solutions will be the focus of next part. Till then...