[ Team LiB ] |
![]() ![]() |
Using Model-View-Controller in Your Web ApplicationsThe Model-View-Controller (MVC) paradigm is a way of dividing an application into three distinct areas:
To put MVC into real-world terms, think of your application as a car. The gas pedal, brake, and steering wheel are controllers. They send input signals to the model, which is the engine, suspension, transmission, and so on. Your speedometer, tachometer, fuel gauge, and idiot lights are all examples of views. They give you some representation of what is happening in the model. Most developers think of MVC in terms of a graphical user interface, because MVC is used extensively in GUI development. With a little imagination, though, you can extend the MVC paradigm to Web development, in terms of servlets and JSPs. The idea is that you split your application into three sections. A servlet handles any requests from the client and acts as a controller. You put your business logic (the model) in Java classes that are neither servlets nor JavaServer Pages. Finally, you use JavaServer Pages to display the view, which is a representation of the model. This is illustrated in Figure 20.3. Figure 20.3. MVC can be used with servlets and JSPs.When applying MVC to a Web application, you have to make some concessions toward the way the Web works. When you use MVC in a GUI application, changes to the model can result in immediate feedback to the user. Because the client and the Web server spend most of their time disconnected from each other, you can't have that kind of dynamic view in a Web application. The important thing is that you concentrate on splitting the model, view, and controller into separate pieces. How Does Model-View-Controller Help?Unfortunately, many applications are developed in a piecemeal fashion. Someone comes to a developer and says, "Hey, can you write a JSP to display X on a browser?" A little while later, that person comes back and says, "Great, now can you put X over here, compute Y, and display Z over here?" After a few rounds of this, the JSP might look beautiful to the user, but the source code probably looks hideous to the developer. The sequence of tasks in the JSP can end up looking something like this:
No one ever intends things to be so convoluted; they just get that way sometimes. By applying MVC to this same sequence of events, you get a cleaner picture. The sequence goes something like this:
An Example ControllerListing 20.1 shows you an example controller that queries a database and then calls a view JSP to show the results. For the sake of brevity, the code is not as robust as it should be. Listing 20.1 Source Code for ControllerServlet.javapackage examples; import java.io.*; import java.util.*; import javax.servlet.*; public class ControllerServlet extends GenericServlet { private static Person[] people = new Person[] { new Person("Samantha Tippin", 9, "770-123-4567"), new Person("Kaitlyn Tippin", 6, "770-123-4567"), new Person("Edward Alexander", 3, "No phone"), new Person("Star Alexander", 3, "Phone off hook"), new Person("Norton Alexander", 12, "No phone") }; public synchronized void service(ServletRequest request, ServletResponse response) throws java.io.IOException, ServletException { // Parse the minimum and maximum ages and go to an error page if they // are invalid. String minimumAgeStr = request.getParameter("minAge"); int minimumAge = 0; try { minimumAge = Integer.parseInt(minimumAgeStr); } catch (Exception exc) { gotoPage("/BadAge.jsp?"+ "reason=Invalid+minimum+age", request, response); } String maximumAgeStr = request.getParameter("maxAge"); int maximumAge = 0; try { maximumAge = Integer.parseInt(maximumAgeStr); } catch (Exception exc) { gotoPage("/BadAge.jsp?"+ "reason=Invalid+maximum+age", request, response); return; } // Get all the people matching the criteria. Vector v = new Vector(); for (int i=0; i < people.length; i++) { if ((people[i].age >= minimumAge) && (people[i].age <= maximumAge)) { v.addElement(people[i]); } } // Store the vector of person objects so the JSP can access it. request.setAttribute("people", v); gotoPage("/ShowPeople.jsp", request, response); return; } // This method comes in handy as a one-liner for forwarding. It should really // check to make sure it can get the dispatcher and do something // predictable if it can't. public void gotoPage(String pageName, ServletRequest request, ServletResponse response) throws IOException, ServletException { RequestDispatcher d = getServletContext(). getRequestDispatcher(pageName); d.forward(request, response); } } An Example ViewThe controller does most of the work. The view will just display the results. We'll reuse the TableServlet class from Hour 10 to display the names in a table. Listing 20.2 shows the example view. Listing 20.2 Source Code for ShowPeople.jsp<html> <body bgcolor="#ffffff"> The following people matched your search criteria: <P> <%-- Invoke the Table servlet, tell it the name of the attribute where the data is stored (data=people), set the border size to 4 on the <table> tag, and describe each column to display. The "people" attribute was sent from the controller servlet and contains a vector of people objects. --%> <jsp:include page="/TableServlet" flush="true"> <jsp:param name="data" value="people"/> <jsp:param name="tableOptions" value="BORDER=4"/> <jsp:param name="column" value="name"/> <jsp:param name="columnType" value="data"/> <jsp:param name="columnHeader" value="Name"/> <jsp:param name="column" value="age"/> <jsp:param name="columnType" value="data"/> <jsp:param name="columnHeader" value="Age"/> <jsp:param name="column" value="phone"/> <jsp:param name="columnType" value="data"/> <jsp:param name="columnHeader" value="Phone"/> </jsp:include> </body> </html> Using Custom Tags in This Example
The front end to this controller-view pairing is a very small HTML page that prompts for the minimum and maximum ages for the query. Listing 20.3 shows the source for the HTML page. Listing 20.3 Source Code for PeopleQuery.html<html> <body> Please enter the minimum and maximum ages to view: <P> <form action="/ControllerServlet" method="post"> Minimum Age: <input type="text" name="minAge"><br> Maximum Age: <input type="text" name="maxAge"><br> <P> <input type="submit" value="Perform Query!"> </form> </body> </html> Finally, Figure 20.4 shows the output of the view class. Most of the view is actually generated by the TableServlet class. Figure 20.4. The View page is responsible for displaying the data retrieved from the model.![]() |
[ Team LiB ] |
![]() ![]() |