ZeePedia

JAVA: MVC Model 2 Architecture

<< JAVA: MVC + Case Study
JAVA: Layers and Tiers >>
img
Web Design & Development ­ CS506
VU
Lesson 40
MVC Model 2 Architecture
We have studied page-centric approach and page-with-bean approach until now. You must be wondering
when we had covered these. Probably these buzz words are new one for you but we already covered these
topics. Let's review these once again.
Page-Centric Approach
A web application that is collection of JSPs. Generally this approach is followed to get started with
developing web applications. This approach is represented in the following diagram:
The page-centric approach has lot of draw backs such as the code becomes a mixture of presentation,
business and data access logic. The maintenance and up-gradation of the application becomes a nightmare.
Scaling of such kind of application is also difficult and lots of code is also get duplicated.
Page-with-Bean Approach (MVC Model1)
This approach is different from page-centric approach in a way that all the business logic goes into
JavaBeans. Therefore, the web application is a collection of JSPs and JavaBeans. But still this approach is
insufficient to separate different kind of logics. We have made an address book example in the last handout
using this approach.
MVC Model 2 Architecture
his architecture introduces a controller. This controller can be implemented using JSP or servlet.
Introducing a controller gives the following advantages:
It centralizes the logic for dispatching requests to the next view based on:
-The Request URL
-Input Parameters
-Application state
It gives the single point of control to perform security checks and to record
logging information
It also encapsulates the incoming data into a form that is usable by the back-end MVC model.
We'll discuss it with the help of an example.
The following figure will help you to understand the architecture and functioning of the application that is
built using MVC Model 2 architecture.
305
img
Web Design & Development ­ CS506
VU
306
img
Web Design & Development ­ CS506
VU
(saveperson.jsp or showperson.jsp) page.
The program flow of this example is shown in the following diagram:
As you can see in the diagram that all the requests are submitted to controller which uses the
JavaBeans and forwards/redirects the user to another view (JSP)? If any exception arises on
controller or JSPs, the control would automatically be transferred to addbookerror.jsp to display an
appropriate message.
How controller differentiates between requests?
Most likely, you must be thinking about it. The simplest solution lies in using the consistent name (e.g.
action) of the submit button across all the pages but with different and unique values. The same rule applies
to hyperlinks that send the action parameter along with value by using query string technique.
This eases the controller's job to identify which page is actually generated the request and what to do next.
The controller simply retrieves the value of action parameter using request.getParameter() method. Now,
if-else structure can be used to compare the possible values of action to act upon the requested task.
Now, let's first see the code of JavaBean that is used in this example.
PersonInfo
This JavaBean is used to represent one person record. The code is given below:
package vu;
import java.io.*;
public class PersonInfo implements Serializable{
private String name;
private String address;
private int phoneNum;
// no argument constructor
public PersonInfo() {
name = "";
address = "";
phoneNum = 0;
}
// setters
public void setName(String n){
name = n;
}
public void setAddress(String a){
address = a;
}
public void setPhoneNum(int pNo){
phoneNum = pNo;
}
// getters
public String getName( ){
return name;
}
public String getAddress( ){
return address;
}
public int getPhoneNum( ){
307
img
Web Design & Development ­ CS506
VU
return phoneNum;
}
} // end class PersonInfo
PersonDAO
This class will help in retrieving and storing person's records in database. The code is given below:
package vu;
import java.util.*; import java.sql.*;
public class PersonDAO{
private Connection con;
// default constructor
public PersonDAO() throws
ClassNotFoundException , SQLException {
establishConnection(); }
// method used to establish connection with db
private void establishConnection()
throws ClassNotFoundException , SQLException {
// establishing conection
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
String conUrl = "jdbc:odbc:PersonDSN";
con = DriverManager.getConnection(conUrl);
}
// used to search the person records against name and returns
the  ArrayList that contains only
//
those PersonInfo
objects which
matches the search criteria i.e. name
public ArrayList retrievePersonList(String pName) throws SQLException {
ArrayList
personList = new ArrayList();
// preparing query
String sql = " SELECT * FROM Person WHERE name = ?";
PreparedStatement pStmt = con.prepareStatement(sql);
pStmt.setString( 1, pName);
// executing query
ResultSet rs = pStmt.executeQuery();
String name;
String add;
int pNo;
while ( rs.next() ) {
name = rs.getString("name");
add = rs.getString("address");
pNo = rs.getInt("phoneNumber");
// creating a CourseOutlineBean object
PersonInfo personBean = new PersonInfo();
personBean.setName(name);
personBean.setAddress(add);
personBean.setPhoneNum(pNo);
308
img
Web Design & Development ­ CS506
VU
// adding a bean to arraylist
personList.add(personBean);
} // end while
return personList;
} // end retrievePersonList
// this method accepts an object of PersonInfo, and stores it into
// the database
public void addPerson(PersonInfo person) throws SQLException{
String sql = " INSERT INTO Person VALUES (?, ?, ?)";
PreparedStatement pStmt = con.prepareStatement(sql);
String name = person.getName();
String add = person.getAddress();
int pNo = person.getPhoneNum();
pStmt.setString( 1 , name );
pStmt.setString( 2 , add );
pStmt.setInt( 3 , pNo );
pStmt.executeUpdate();
} // end addPerson  // overriding finalize method to release acquired resources
public void finalize( ) {
try{
con.close();
}
}catch(SQLException sqlex){
System.out.println(sqlex);
}
} // end finalize
} // end PersonDAO class
addperson.jsp
This page is used for entering a new person record into the database. Note that a hyperlink is also given at
the ottom of the page that takes the user to searchperson.jsp.
Note: Since we are following MVC model 2 architecture, so all the hyperlinks will also sends the request
to controller first which redirects the user to requested page.
309
img
Web Design & Development ­ CS506
VU
The code of above page is given below:
<%-- Although there are no chances of exception to arise on this page, for consistency, error
page is defined on top of all JSPs
--%>
<%@page errorPage="addbookerror.jsp" %>
<html>
<body>
<center>
<h2> Address Book </h2>
<h3> Add New Person</h3>
<%-- As mentioned in MVC2, all the requests are submitted to controller, that's why
action's contains the value of "controller.jsp"
--%>
<form name ="register" action="controller.jsp" />
<TABLE BORDER="1" >
<TR>  <TD> <h4> Name </h4>  </TD> <TD> <input type="text" name="name" />
</TD>
</TR>
<TR>  <TD> <h4> Address </h4> </TD>  <TD> <input type="text" name="address"
/> </TD>
</TR>
<TR>  <TD> <h4>Phone Number</h4>
</TD> <TD> <input type="text"
name="phoneNum" /> </TD>
</TR>
<TR>  <TD COLSPAN="2" ALIGN="CENTER"">
<%-- As described above the technique to differentiate between the requests, the
name of the button is "action" with value "save".
--%>
<input type="submit" name ="action" value="save" />
<input type="reset" value="clear" />
</TD>
310
img
Web Design & Development ­ CS506
VU
</TR>
</TABLE>
</form>
<h4>
<%- The hyperlink will also sends the request to controller
Note the action parameter with its value are also part of hyperlink
using
the query string technique.
--%>
<a href="controller.jsp?action=searchperson" >
Search Person </a>
</h4>
</center>
</body>
</html>
searchperson.jsp
This JSP is used to search the person record against name given in the text field. A hyperlink is also given
at the bottom of addperson.jsp.
The code that is used to generate that above page is given below:
<%-- defining error page --%>
<%@page errorPage="addbookerror.jsp" %>
< html>
<body>
<center>
<h2> Address Book </h2>
<h3> Search Person</h3>
<form name ="search" action="controller.jsp" />
<TABLE BORDER="1" >
<TR> <TD> <h4> Name </h4>  </TD> <TD> <input type="text" name="name" />
</TD>
</TR>
<TR>
<TD COLSPAN="2" ALIGN="CENTER"">
311
img
Web Design & Development ­ CS506
VU
<%- The name of the button is still "action" but with different value
"search".
--%>
<input type="submit" name ="action" value="search" />
<input type="reset" value="clear" />
</TD>
</TR>
</TABLE>
</form>
<h4>
<%- The action parameter with different value "addperson" are part of hyperlink
here as well.
--%>
<a
href="controller.jsp?action=addperson"
> Add Person </a>
</h4>
</center>
</body>
</html>
controller.jsp
As mentioned earlier that controller.jsp identifies the page which initiates the request and use JavaBeans to
save/search persons to/from database. Also its job list includes redirecting the user to appropriate page.
Since this JSP is doing only processing therefore no view available. Let's check it out its code:
<%-- defining error page --%>
<%@page errorPage="addbookerror.jsp" %>
<%-- importing required packages. package vu contains JavaBeans --%>
<%@page import ="java.util.*" %> <%@page
import = "vu.*" %>
<html>
<body>
<%-- declaring PersonDAO object--%>
<jsp:useBean id="pDAO" class="vu.PersonDAO" scope="page" />
<%- scriptlet to identify JSP for redirection purpose if request comes from hyperlinks
--%>
<%
// retrieving action parameter value
// Remember that "action" is the name of buttons as well
// it is used in hyperlinks in making of query string
String action = request.getParameter("action");
// if "Add Person" hyperlink is clicked
if (action.equals("addperson") ){
response.sendRedirect("addperson.jsp");
// if "Search Person" hyperlink is clicked
} else if (action.equals("searchperson")){
response.sendRedirect("searchperson.jsp");
// if "save" button is clicked of addperson.jsp
}else if (action.equals("save")) {
%>
// declaring PersonInfo obeject
312
img
Web Design & Development ­ CS506
VU
<jsp:useBean id="personBean" class="vu.PersonInfo" scope="page"/>
<%--
setting all properties of personBean object with input
parameters using *
--%>
<jsp:setProperty name="personBean" property="*" />
<%-- to insert record into database--%>
<%
pDAO.addPerson(personBean);
// redirecting user to saveperson.jsp
response.sendRedirect("saveperson.jsp");
%>
<%-- if "search" button is clicked on searchperson.jsp --%>
<%
}else if (action.equals("search") ) {
String pName = request.getParameter("name");  ArrayList personList =
pDAO.retrievePersonList(pName);
// storing personList(contains PersonInfo objects) into  // request hashmap
request.setAttribute("list", personList);
%>
<%-- forwarding request to showperson.jsp to retrievestored arraylist ("list")
--%>
<jsp:forward page="showperson.jsp" />
<%
} // end if page == search
%>
</body>
</html>
saveperson.jsp
This page displays a successful message indicating that person record is saved. Its also give the options to
the user to move on to addperson.jsp or searchperson.jsp through hyperlinks. Note that these hyperlinks
also first take the user to controller.jsp then on to requested page.
The code of saveperson.jspis given below:
<%-- defining error page --%>
<%@page errorPage="addbookerror.jsp" %>
<html>
313
img
Web Design & Development ­ CS506
VU
<body>
<center>
<h3> New Person Record is saved successfully!</h3>
<h4>
<a href="controller.jsp?action=addperson" >  Add
Person </a>
</h4>
</h4>
<a href="controller.jsp?action=searchperson" > Search
Person  </a>
</h4>
</center>
</body>
</html>
showperson.jsp
This following figure gives you the view when name "saad" is searched.
Below, the code of showperson.jsp is given:
<%-- defining error page --%>
<%@page errorPage="addbookerror.jsp" %>
<%-- importing required packages --%>
<%@page import="java.util.*" %> <%@page
import="vu.*" %>
<html> <body>
<center>
<h2> Address Book </h2>
<h3> Following results meet your search criteria</h3>
<TABLE BORDER="1" >
<TR>
<TH> Name </TH>
<TH> Address </TH>
<TH> PhoneNum </TH>
</TR>
<%
// retrieving arraylist stored on controller.jsp to display PersonInfo objects
ArrayList personList = (ArrayList)request.getAttribute("list"); PersonInfo person =
314
img
Web Design & Development ­ CS506
VU
null;
for(int i=0; i<personList.size(); i++) {
person = (PersonInfo)personList.get(i);
%>
<%-- displaying PersonInfo details--%>
<TR> <TD> <%= person.getName()%> </TD> <TD> <%= person.getAddress()%>
</TD> <TD> <%= person.getPhoneNum()%> </TD>
</TR>
<%
} // end for
%>
</TABLE >
<h4>
<a href="controller.jsp?action=addperson"> Add Person </a> <a
href="controller.jsp?action=searchperson">Search Person</a>
</h4>
</c enter>
</body>
</html>
addbookerror.jsp
User will view this page only when any sort of exception is generated. The code of this page is given
below:
<%-- indicating that this is an error page --%>
<%@page isErrorPage="true" %>
<%-- importing class --%>
<%@page import = "java.sql.SQLException" %>
<html>
<head>  <title>Error</title>  </head>
<body>
<h2>
Error Page
</h2>
<h3>
<%-- scriptlet to determine exception type --%>
<%
if (exception instanceof SQLException) {
%>
An SQL Exception
<%
} else if (exception instanceof ClassNotFoundException){
%>
A Class Not Found Exception
<%
} else {
%>
A Exception
<%
} // end if-else
%>
315
img
Web Design & Development ­ CS506
VU
<%-- end scriptlet to determine exception type --%>
occured while interacting with the database
</h3>
<h3>
The Error Message was
<%= exception.getMessage() %>
</h3>
<h3 > Please Try Again Later! </h3>
<%-- hyperlinks to return back to adperson.jsp orsearchperson.sjp
--%>
<h3>
<a
href="controller.jsp?action=addperson"
> Add Person </a>
<a href="controller.jsp?action=searchperson"
> Search Person  </a>
</h3>
</body>
</html>
JSP is the Right Choice as a Controller?
Since JSP that is performing the job of controller is doing only processing and there is no view available of
it. It includes the logic of selecting JSP and to retrieve/store records from/to dataset using JavaBeans.
But remember the reason for introducing JSPs? JavaServer Pages are built for presentation (view) only so
JSP is really not a good place for such kind of logic. Concluding, what's the option we have? The answer
is, use Servlets as controller.
Introducing a Servlet as Controller
Remove the controller.jsp from the previous example code and add ControllerServlet.java (a servlet) into
this example. This ControllerServlet.java performs the same job that was previously performed by
controller.jsp.
Besides adding ControllerServlet.java, you have to modify all the addresses which are previously pointing
to controller.jsp. For example the value of action attribute of form tag & the address of hyperlink in all
concerned pages.
If controller is defined in web.xml as an alias of ControllerServlet.java, consider the following fragment of
code which shows the value of action attribute of form tag before and after introducing change.
When controller.jsp is acting as a controller
<form name ="register" action="controller.jsp" />
When ControllerServlet.java is acting as a controller then value of action attribute becomes:
<form name ="register" action="controller" />
Similarly, the following comparison shows the code of hyperlinks used in the previous example before and
after making changes
When controller.jsp is acting as a controller
<a href="controller.jsp?action=searchperson" >
Search Person
</a>
When ControllerServlet.java is acting as a controller
<a href="controller?action=searchperson" >
Search Person
</a>
316
img
Web Design & Development ­ CS506
VU
Passing Exceptions to an Error JSP from a Servlet
Servlet can use existing error pages (like addbookerror.jsp) to pass on the exceptions. Set the request
attribute to javax.servlet.jsp.JspExcpetion with the exception object you want to pass. After that forwards
the request to error page.
For example, the following code snippet is taken from ControllerServlet.java to demonstrate how to pass
SQLExceptionto addbookerror.jsp
..................
..................
}catch (SQLException sqlex){
// setting SQLException instance
request.setAttribute("javax.servlet.jsp.JspException" ,
sqlex); RequestDispatcher rd =
request.getRequestDispatcher("addbookerror.jsp");
rd.forward(request, response);
} // end catch
CotrollerServlet.java
The following code is of servlet that is acting as a controller
package controller;
import vu.*;
import java.io.*;import java.net.*;
import java.sql.*; import java.util.*;
import javax.servlet.*; import javax.servlet.http.*;
public class ControllerServlet extends HttpServlet {
// This method only calls processRequest()
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws
ServletException, IOException {
processRequest(request, response);
}
// This method only calls processRequest()
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws
ServletException, IOException {
processRequest(request, response);
}
protected void processRequest(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
// retrieving value of action parameter
String userAction = request.getParameter("action");
// if request comes to move to addperson.jsp from hyperlink
if (userAction.equals("addperson") ) {
response.sendRedirect("addperson.jsp");
// if request comes to move to searchperson.jsp from hyperlink
} else if (userAction.equals("searchperson")) {
response.sendRedirect("searchperson.jsp");
// if "save" button clicked on addperson.jsp to add new record
} if (userAction.equals("save")) {
// this method defined below
addPerson(request,response);
317
img
Web Design & Development ­ CS506
VU
// if "search" button clicked on searchperson.jsp for search
} else if (userAction.equals("search"))
{
// this method defined below
searchPerson(request,response);
}
} // end processRequest()
// if request comes to add/save person
private void addPerson(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{ try
{
// creating PersonDAO object
PersonDAO pDAO = new PersonDAO();
// creating PersonInfo object
PersonInfo person = new PersonInfo();
// setting properties of Person object
// setting name property
String pName = request.getParameter("name");
person.setName(pName);
// setting address propertyt
String add = request.getParameter("address");
person.setAddress(add);
// setting phoneNumb property
String pNo = request.getParameter("phoneNum");
int phoneNum = Integer.parseInt(pNo);
person.setPhoneNum(phoneNum);
// calling PersonDAO method to save data into database
pDAO.addPerson(person);
// redirecting page to saveperson.jsp
response.sendRedirect("saveperson.jsp");
}catch (SQLException sqlex){
// setting SQLException instance
request.setAttribute("javax.servlet.jsp.JspException" , sqlex);
RequestDispatcher rd = request.getRequestDispatcher("addbookerror.jsp");
rd.forward(request, response); }
catch (ClassNotFoundException cnfe){
// setting ClassNotFoundException instance
request.setAttribute("javax.servlet.jsp.JspException" , cnfe);
RequestDispatcher rd =
request.getRequestDispatcher("addbo
okerror.jsp"); rd.forward(request,
response);
}
}// end addperson()
// if request comes to search person record from database
318
img
Web Design & Development ­ CS506
VU
private void searchPerson(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
try {
// creating PersonDAO object
PersonDAO pDAO = new PersonDAO();
String pName = request.getParameter("name");
// calling DAO method to retrieve personlist from database // against name
ArrayList personList = pDAO.retrievePersonList(pName);
request.setAttribute("list", personList);
// forwarding request to showpeson, so it can render personlist
RequestDispatcher rd = request.getRequestDispatcher("showperson.jsp");
rd.forward(request, response);
}catch (SQLException sqlex){
// setting SQLException instance
request.setAttribute("javax.servlet.jsp.JspException" , sqlex);
RequestDispatcher rd =
request.getRequestDispatcher("addboo
kerror.jsp"); rd.forward(request,
response);
}catch (ClassNotFoundException cnfe){
// setting ClassNotFoundException instance
request.setAttribute("javax.servlet.jsp.JspException" , cnfe);
RequestDispatcher rd = request.getRequestDispatcher("addbookerror.jsp");
rd.forward(request, response);
}
}// end searchPerson()
} // end ControllerServlet
web.xml
As you already familiar, for accessing a servlet, you need to define a URL pattern in web.xml. This is
shown below:
<?xml version="1.0" encoding="UTF-8"?> <web-app>
<servlet>
<servlet-name> ControllerServlet </servlet-name>
<servlet-class> controller.ControllerServlet </servlet-class>
</servlet>
<servlet-mapping>
<servlet-name> ControllerServlet </servlet-name>
<url-pattern> /controller </url-pattern>
</servlet-mapping>
</web-app>
eferences:
. Java A Lab Course by Umair Javed.
. Java E-commerce course at Stanford
319