Chapter 7 How to structure a web application with the MVC pattern Murach’s Java Servlets/JSP (2nd Ed.), C7 © 2008, Mike Murach & Associates, Inc. Slide 1 Objectives Applied Use the MVC pattern to develop your web applications so servlets control the processing and JSPs do the presentation. Provide for server-side data validation in your applications. Use include files in your JSPs at compile-time or runtime. Use the web.xml file to set initialization parameters and use your servlets to get the parameters. Use the web.xml file to implement custom error handling. Murach’s Java Servlets/JSP (2nd Ed.), C7 © 2008, Mike Murach & Associates, Inc. Slide 2 Objectives (cont.) Knowledge Describe the Model 1 architecture. Describe the Model-View-Controller pattern Explain how the MVC pattern can improve application development. Distinguish between the use of JavaScript and servlets for data validation. Describe the use of include files. Murach’s Java Servlets/JSP (2nd Ed.), C7 © 2008, Mike Murach & Associates, Inc. Slide 3 The code for the servlet package email; import import import import import java.io.*; javax.servlet.*; javax.servlet.http.*; business.User; data.UserIO; public class AddToEmailListServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // get parameters from the request String firstName = request.getParameter("firstName"); String lastName = request.getParameter("lastName"); String emailAddress = request.getParameter("emailAddress"); Murach’s Java Servlets/JSP (2nd Ed.), C7 © 2008, Mike Murach & Associates, Inc. Slide 4 The code for the servlet (cont.) // get a relative file name ServletContext context = getServletContext(); String path = context.getRealPath("/WEB-INF/EmailList.txt"); // use regular Java classes User user = new User(firstName, lastName, emailAddress); UserIO.addRecord(user, path); // store the User object in the request object request.setAttribute("user", user); // forward request and response objects to JSP page String url = "/display_email_entry.jsp"; RequestDispatcher dispatcher = getServletContext().getRequestDispatcher(url); dispatcher.forward(request, response); } } Murach’s Java Servlets/JSP (2nd Ed.), C7 © 2008, Mike Murach & Associates, Inc. Slide 5 The code for the JSP <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <title>Murach's Java Servlets and JSP</title> </head> <body> <h1>Thanks for joining our email list</h1> <p>Here is the information that you entered:</p> <%@ page import="business.User" %> <% User user = (User) request.getAttribute("user"); %> <table cellspacing="5" cellpadding="5" border="1"> <tr> <td align="right">First name:</td> <td><%= user.getFirstName() %></td> </tr> Murach’s Java Servlets/JSP (2nd Ed.), C7 © 2008, Mike Murach & Associates, Inc. Slide 6 The code for the JSP (cont.) <tr> <td align="right">Last name:</td> <td><%= user.getLastName() %></td> </tr> <tr> <td align="right">Email address:</td> <td><%= user.getEmailAddress() %></td> </tr> </table> <p>To enter another email address, click on the Back <br> button in your browser or the Return button shown <br> below.</p> <form action="join_email_list.html" method="post"> <input type="submit" value="Return"> </form> </body> </html> Murach’s Java Servlets/JSP (2nd Ed.), C7 © 2008, Mike Murach & Associates, Inc. Slide 7 The Model 1 architecture Browser HTTP request HTTP response JSP display_email_entry.jsp Java classes User.class UserIO.class Murach’s Java Servlets/JSP (2nd Ed.), C7 Data store © 2008, Mike Murach & Associates, Inc. Slide 8 The Model 1 architecture The Model 1 architecture is sometimes adequate for web applications with limited processing requirements. With this architecture, JSPs handle all of the processing and presentation for the application. In the Model 1 architecture, the JSPs can use regular Java classes to store the data of the application and to do the business processing of the application. The data store can be a database or one or more disk files. This is often referred to as persistent data storage because it exists after the application ends. Murach’s Java Servlets/JSP (2nd Ed.), C7 © 2008, Mike Murach & Associates, Inc. Slide 9 The Model-View-Controller pattern Browser HTTP response HTTP request Controller AddToEmailListServlet.class View show_email_entry.jsp Model User.class UserIO.class Data store Murach’s Java Servlets/JSP (2nd Ed.), C7 © 2008, Mike Murach & Associates, Inc. Slide 10 The Model-View-Controller (MVC) pattern The Model-View-Controller (MVC) pattern is commonly used to structure web applications that have significant processing requirements. That makes them easier to code and maintain. This pattern is also known as the Model 2 architecture. In the MVC pattern, the model consists of business objects like the User object, the view consists of HTML pages and JSPs, and the controller consists of servlets. Usually, the methods of data classes like the UserIO class are used to read and write business objects like the User object to and from the data store. When you use the MVC pattern, you try to construct each layer so it’s as independent as possible. Then, if you need to make changes to one layer, any changes to the other layers are minimized. Murach’s Java Servlets/JSP (2nd Ed.), C7 © 2008, Mike Murach & Associates, Inc. Slide 11 Two methods available from the request object Method setAttribute(String name, Object o) getAttribute(String name) Murach’s Java Servlets/JSP (2nd Ed.), C7 Description Stores any object in the request as an attribute and specifies a name for the attribute. Attributes are reset between requests. Returns the value of the specified attribute as an Object type. If no attribute exists for the specified name, this method returns a null value. © 2008, Mike Murach & Associates, Inc. Slide 12 How to set a request attribute User user = new User(firstName, lastName, emailAddress); request.setAttribute("user", user); How to get a request attribute User user = (User) request.getAttribute("user"); How to set a request attribute for a primitive type int id = 1; request.setAttribute("id", id); How to get a request attribute for a primitive type int id = (Integer) request.getAttribute("id"); Murach’s Java Servlets/JSP (2nd Ed.), C7 © 2008, Mike Murach & Associates, Inc. Slide 13 A method of the ServletContext object for working with paths Method getRequestDispatcher(String path) Description Returns a RequestDispatcher object for the specified path. A method of the RequestDispatcher object Method forward(ServletRequest request, ServletResponse response) Murach’s Java Servlets/JSP (2nd Ed.), C7 Description Forwards the request and response objects to another resource on the server (usually a JSP or servlet). © 2008, Mike Murach & Associates, Inc. Slide 14 How to forward the request to an HTML page String url = "/display_email_entry.html"; RequestDispatcher dispatcher = getServletContext().getRequestDispatcher(url); dispatcher.forward(request, response); How to forward the request to a JSP String url = "/display_email_entry.jsp"; RequestDispatcher dispatcher = getServletContext().getRequestDispatcher(url); dispatcher.forward(request, response); How to forward the request to a servlet String url = "/cart/displayInvoice"; RequestDispatcher dispatcher = getServletContext().getRequestDispatcher(url); dispatcher.forward(request, response); Murach’s Java Servlets/JSP (2nd Ed.), C7 © 2008, Mike Murach & Associates, Inc. Slide 15 A method of the HttpServletResponse class Method sendRedirect(String path) Murach’s Java Servlets/JSP (2nd Ed.), C7 Description Sends a temporary redirect response to the client using the specified redirect location URL. © 2008, Mike Murach & Associates, Inc. Slide 16 How to redirect a response relative to the current directory response.sendRedirect("join_email_list.html"); How to redirect a response relative to the servlet engine response.sendRedirect( "/musicStore/email/join_email_list.jsp"); How to redirect a response to a different web server response.sendRedirect("http://www.murach.com/email/"); Murach’s Java Servlets/JSP (2nd Ed.), C7 © 2008, Mike Murach & Associates, Inc. Slide 17 The JavaScript that validates a form <script language="JavaScript"> function validate(form) { if (form.firstName.value=="") { alert("Please fill in your first name"); form.firstName.focus(); } else if (form.lastName.value=="") { alert("Please fill in your last name"); form.lastName.focus(); } else if (form.emailAddress.value=="") { alert("Please fill in your email address"); form.emailAddress.focus(); } Murach’s Java Servlets/JSP (2nd Ed.), C7 © 2008, Mike Murach & Associates, Inc. Slide 18 The JavaScript that validates a form (cont.) else { form.submit(); } } </script> Murach’s Java Servlets/JSP (2nd Ed.), C7 © 2008, Mike Murach & Associates, Inc. Slide 19 The HTML for the form <form action="addToEmailList" method="post"> <table cellspacing="5" border="0"> <tr> <td align="right">First name:</td> <td><input type="text" name="firstName" value="<%= user.getFirstName() %>"></td> </tr> <tr> <td align="right">Last name:</td> <td><input type="text" name="lastName" value="<%= user.getLastName() %>"></td> </tr> <tr> <td align="right">Email address:</td> <td><input type="text" name="emailAddress" value="<%= user.getEmailAddress() %>"></td> </tr> Murach’s Java Servlets/JSP (2nd Ed.), C7 © 2008, Mike Murach & Associates, Inc. Slide 20 The HTML for the form (cont.) <tr> <td></td> <td><br><input type="button" value="Submit" onClick="validate(this.form)"></td> </tr> </table> </form> Murach’s Java Servlets/JSP (2nd Ed.), C7 © 2008, Mike Murach & Associates, Inc. Slide 21 The dialog box that’s displayed when an entry isn’t made Murach’s Java Servlets/JSP (2nd Ed.), C7 © 2008, Mike Murach & Associates, Inc. Slide 22 How to use JavaScript to validate the data on the client When you use JavaScript to display validation messages, they appear in standard dialog boxes. If you want to display error messages in an HTML page or JSP, you can use servlets to validate data on the server side. Murach’s Java Servlets/JSP (2nd Ed.), C7 © 2008, Mike Murach & Associates, Inc. Slide 23 A servlet that validates data package email; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; import business.User; import data.UserIO; public class AddToEmailListServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // get parameters from the form String firstName = request.getParameter("firstName"); String lastName = request.getParameter("lastName"); String emailAddress = request.getParameter("emailAddress"); Murach’s Java Servlets/JSP (2nd Ed.), C7 © 2008, Mike Murach & Associates, Inc. Slide 24 A servlet that validates data (cont.) // create the User object from the parameters User user = new User(firstName, lastName, emailAddress); // validate the parameters String message = ""; String url = ""; if (firstName.length() == 0 || lastName.length() == 0 || emailAddress.length() == 0) { message = "Please fill out all three text boxes."; url = "/join_email_list.jsp"; } else { message = ""; Murach’s Java Servlets/JSP (2nd Ed.), C7 © 2008, Mike Murach & Associates, Inc. Slide 25 A servlet that validates data (cont.) ServletContext context = getServletContext(); String path = context.getRealPath( "/WEB-INF/EmailList.txt"); UserIO.addRecord(user, path); url = "/display_email_entry.jsp"; } request.setAttribute("user", user); request.setAttribute("message", message); // forward request and response to the view RequestDispatcher dispatcher = getServletContext().getRequestDispatcher(url); dispatcher.forward(request, response); } } Murach’s Java Servlets/JSP (2nd Ed.), C7 © 2008, Mike Murach & Associates, Inc. Slide 26 A JSP that displays a validation message <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <title>Murach's Java Servlets and JSP</title> </head> <body> <%@ page import="business.User" %> <% // get attributes from the request User user = (User) request.getAttribute("user"); String message = (String) request.getAttribute("message"); // handle null values if (user == null) user = new User(); if (message == null) message = ""; %> Murach’s Java Servlets/JSP (2nd Ed.), C7 © 2008, Mike Murach & Associates, Inc. Slide 27 A JSP that displays a validation message (cont.) <h1>Join our email list</h1> <p>To join our email list, enter your name and email address below. <br> Then, click on the Submit button.</p> <p><i><%= message %></i></p> <form action="addToEmailList" method="post"> <table cellspacing="5" border="0"> <tr> <td align="right">First name:</td> <td><input type="text" name="firstName" value="<%= user.getFirstName() %>"></td> </tr> <tr> <td align="right">Last name:</td> <td><input type="text" name="lastName" value="<%= user.getLastName() %>"></td> </tr> Murach’s Java Servlets/JSP (2nd Ed.), C7 © 2008, Mike Murach & Associates, Inc. Slide 28 A JSP that displays a validation message (cont.) <tr> <td align="right">Email address:</td> <td><input type="text" name="emailAddress" value="<%= user.getEmailAddress() %>"></td> </tr> <tr> <td></td> <td><br><input type="submit" value="Submit"></td> </tr> </table> </form> </body> </html> Murach’s Java Servlets/JSP (2nd Ed.), C7 © 2008, Mike Murach & Associates, Inc. Slide 29 The JSP that’s displayed when the application is first started Murach’s Java Servlets/JSP (2nd Ed.), C7 © 2008, Mike Murach & Associates, Inc. Slide 30 The JSP that’s displayed when an entry isn’t made Murach’s Java Servlets/JSP (2nd Ed.), C7 © 2008, Mike Murach & Associates, Inc. Slide 31 A header file named header.html <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <title>Murach's Java Servlets and JSP</title> </head> <body> Murach’s Java Servlets/JSP (2nd Ed.), C7 © 2008, Mike Murach & Associates, Inc. Slide 32 A footer file named footer.jsp <%@ page import="java.util.*" %> <% // initialize the current year that's used in the // copyright notice GregorianCalendar currentDate = new GregorianCalendar(); int currentYear = currentDate.get(Calendar.YEAR); %> <p><small> &copy; Copyright <%= currentYear %> Mike Murach &amp; Associates, Inc. All rights reserved </small></p> </body> </html> Murach’s Java Servlets/JSP (2nd Ed.), C7 © 2008, Mike Murach & Associates, Inc. Slide 33 A JSP file that uses both include files <%@ include file="/includes/header.html" %> <h1>Thanks for joining our email list</h1> <p>Here is the information that you entered:</p> <%@ page import="business.User" %> <% User user = (User) request.getAttribute("user"); %> <table cellspacing="5" cellpadding="5" border="1"> <tr><td align="right">First name:</td> <td><%= user.getFirstName() %></td> </tr> <tr><td align="right">Last name:</td> <td><%= user.getLastName() %></td> </tr> <tr><td align="right">Email address:</td> <td><%= user.getEmailAddress() %></td> </tr> </table> Murach’s Java Servlets/JSP (2nd Ed.), C7 © 2008, Mike Murach & Associates, Inc. Slide 34 A JSP file that uses both include files (cont.) <p>To enter another email address, click on the Back <br> button in your browser or the Return button shown <br> below.</p> <form action="join_email_list.jsp" method="post"> <input type="submit" value="Return"> </form> <%@ include file="/includes/footer.jsp" %> Murach’s Java Servlets/JSP (2nd Ed.), C7 © 2008, Mike Murach & Associates, Inc. Slide 35 The JSP page Murach’s Java Servlets/JSP (2nd Ed.), C7 © 2008, Mike Murach & Associates, Inc. Slide 36 Another JSP page that uses the same header and footer Murach’s Java Servlets/JSP (2nd Ed.), C7 © 2008, Mike Murach & Associates, Inc. Slide 37 How to include a file in a JSP at compile-time with an include directive Syntax <%@ include file="fileLocationAndName" %> Examples <%@ include file="/includes/header.html" %> <%@ include file="/includes/footer.jsp" %> How to include a file in a JSP at runtime with an include action Syntax <jsp:include page="fileLocationAndName" /> Examples <jsp:include page="/includes/header.html" /> <jsp:include page="/includes/footer.jsp" /> Murach’s Java Servlets/JSP (2nd Ed.), C7 © 2008, Mike Murach & Associates, Inc. Slide 38 Two techniques for including files in a JSP To include a file in a JSP at compile-time, you use the include directive. When you use the include directive, the code in the included file becomes part of the generated servlet. As a result, any changes to the included file won’t appear in the JSP until the JSP is regenerated and recompiled. However, some of the newer web servers automatically detect changes to included files and automatically regenerate and recompile the servlets for the JSPs that need to be updated. To include a file in a JSP at runtime, you use the include action. When you use the include action, the generated servlet uses a runtime call to get the included file, and any changes to the included file appear in the JSP the next time it is requested. Murach’s Java Servlets/JSP (2nd Ed.), C7 © 2008, Mike Murach & Associates, Inc. Slide 39 The web.xml file for the Email List application <?xml version="1.0" encoding="UTF-8"?><web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <context-param> <param-name>custServEmail</param-name> <param-value>custserv@murach.com</param-value> </context-param> <servlet> <servlet-name>AddToEmailListServlet</servlet-name> <servlet-class>email.AddToEmailListServlet </servlet-class> <init-param> <param-name>relativePathToFile</param-name> <param-value>/WEB-INF/EmailList.txt </param-value> </init-param> </servlet> Murach’s Java Servlets/JSP (2nd Ed.), C7 © 2008, Mike Murach & Associates, Inc. Slide 40 The web.xml file for the Email List application (cont.) <servlet-mapping> <servlet-name>AddToEmailListServlet</servlet-name> <url-pattern>/addToEmailList</url-pattern> </servlet-mapping> <!-- you can comment out these tags when the app is in development --> <error-page> <error-code>404</error-code> <location>/error_404.jsp</location> </error-page> <error-page> <exception-type>java.lang.Throwable</exception-type> <location>/error_java.jsp</location> </error-page> Murach’s Java Servlets/JSP (2nd Ed.), C7 © 2008, Mike Murach & Associates, Inc. Slide 41 The web.xml file for the Email List application (cont.) <session-config> <session-timeout>30</session-timeout> </session-config> <welcome-file-list> <welcome-file>join_email_list.jsp</welcome-file> </welcome-file-list> </web-app> Murach’s Java Servlets/JSP (2nd Ed.), C7 © 2008, Mike Murach & Associates, Inc. Slide 42 How to work with the web.xml file The web.xml file is stored in the WEB-INF directory for an application. When Tomcat starts, it reads the web.xml file. If the elements in the web.xml aren’t in the correct order, Tomcat will display an error message when it reads the web.xml file. After you modify the web.xml file, you must redeploy the application so the changes take effect. Or, you can restart Tomcat. Murach’s Java Servlets/JSP (2nd Ed.), C7 © 2008, Mike Murach & Associates, Inc. Slide 43 XML tags that set initialization parameters in a web.xml file <context-param> <param-name>custServEmail</param-name> <param-value>custserv@murach.com</param-value> </context-param> <servlet> <servlet-name>AddToEmailListServlet</servlet-name> <servlet-class>email.AddToEmailListServlet </servlet-class> <init-param> <param-name>relativePathToFile</param-name> <param-value>/WEB-INF/EmailList.txt</param-value> </init-param> </servlet> Murach’s Java Servlets/JSP (2nd Ed.), C7 © 2008, Mike Murach & Associates, Inc. Slide 44 XML elements for working with initialization parameters Element <context-param> <servlet> <servlet-name> <servlet-class> <init-param> <param-name> <param-value> Murach’s Java Servlets/JSP (2nd Ed.), C7 Description Defines a parameter that’s available to all servlets within an application. Identifies a specific servlet within the application. Defines the name for the servlet that’s used in the rest of the web.xml file. Identifies the servlet by specifying the servlet’s package and class name. Defines a name/value pair for an initialization parameter for a servlet. Defines the name of a parameter. Defines the value of a parameter. © 2008, Mike Murach & Associates, Inc. Slide 45 How to work with initialization parameters To create an initialization parameter that will be available to all servlets (called a context initialization parameter), you code the param-name and param-value elements within the context-param element. To create an initialization parameter that will be available to a specific servlet (called a servlet initialization parameter), you code the param-name and param-value elements within the init-param element. But first, you must identify the servlet by coding the servlet, servlet-name, and servlet-class elements. Murach’s Java Servlets/JSP (2nd Ed.), C7 © 2008, Mike Murach & Associates, Inc. Slide 46 Two methods of the GenericServlet class Method getServletContext() getServletConfig() Murach’s Java Servlets/JSP (2nd Ed.), C7 Description Returns a ServletContext object that contains information about the entire web application's context. Returns a ServletConfig object that contains information about a single servlet’s configuration. © 2008, Mike Murach & Associates, Inc. Slide 47 A method of the ServletContext and ServletConfig interfaces Method getInitParameter(String name) Murach’s Java Servlets/JSP (2nd Ed.), C7 Description Returns a String object that contains the value of the specified initialization parameter. If the parameter doesn’t exist, this method returns a null value. © 2008, Mike Murach & Associates, Inc. Slide 48 Code that gets an initialization parameter that’s available to all servlets ServletContext context = this.getServletContext(); String custServEmail = context.getInitParameter("custServEmail"); Code that gets an initialization parameter that’s available to the current servlet only ServletConfig config = this.getServletConfig(); String relativePath = config.getInitParameter("relativePathToFile"); The getInitParameter methods To get an initialization parameter that’s available to all servlets, you use the getInitParameter method of the ServletContext object. To get an initialization parameter for a specific servlet, you use the getInitParameter method of the ServletConfig object. Murach’s Java Servlets/JSP (2nd Ed.), C7 © 2008, Mike Murach & Associates, Inc. Slide 49 XML elements for working with error handling Element <error-page> <error-code> <exception-type> <location> Murach’s Java Servlets/JSP (2nd Ed.), C7 Description Specifies an HTML page or JSP that’s displayed when the application encounters an uncaught exception or a certain type of HTTP status code. Specifies the number of a valid HTTP status code. Uses the fully qualified class name to specify a Java exception. Specifies the location of the HTML page or JSP that’s displayed. © 2008, Mike Murach & Associates, Inc. Slide 50 The XML tags that provide error-handling for a HTTP 404 status code <error-page> <error-code>404</error-code> <location>/error_404.jsp</location> </error-page> The code for a file named error_404.jsp <%@ include file="/includes/header.html" %> <%@ page isErrorPage="true" %> <h1>404 Error</h1> <p>The server was not able to find the file you requested.</p> <p>To continue, click the Back button.</p> <br> <%@ include file="/includes/footer.jsp" %> Murach’s Java Servlets/JSP (2nd Ed.), C7 © 2008, Mike Murach & Associates, Inc. Slide 51 The XML tags that provide error-handling for all Java exceptions <error-page> <exception-type>java.lang.Throwable</exception-type> <location>/error_java.jsp</location> </error-page> Murach’s Java Servlets/JSP (2nd Ed.), C7 © 2008, Mike Murach & Associates, Inc. Slide 52 The code for a file named error_java.jsp <%@ include file="/includes/header.html" %> <%@ page isErrorPage="true" %> <h1>Java Error</h1> <p>Sorry, Java has thrown an exception.</p> <p>To continue, click the Back button.</p> <br> <h2>Details</h2> <p> Type: <%= exception.getClass() %><br> Message: <%= exception.getMessage() %><br> </p> <%@ include file="/includes/footer.jsp" %> Murach’s Java Servlets/JSP (2nd Ed.), C7 © 2008, Mike Murach & Associates, Inc. Slide 53 The JSP page for the 404 error Murach’s Java Servlets/JSP (2nd Ed.), C7 © 2008, Mike Murach & Associates, Inc. Slide 54 The JSP page that’s displayed when a Java exception is thrown Murach’s Java Servlets/JSP (2nd Ed.), C7 © 2008, Mike Murach & Associates, Inc. Slide 55 How to implement custom error handling In the web.xml file, you can use the error-page element to specify the error pages that should be displayed when the application encounters (1) specific HTTP status codes or (2) uncaught exceptions. By default, the Internet Explorer uses its own error pages for HTTP status codes. As a result, if you want to use this browser to view a custom page, you must select the Tools Internet Options command and use the Advanced tab of the dialog box to deselect the “Show friendly HTTP error messages” option. Murach’s Java Servlets/JSP (2nd Ed.), C7 © 2008, Mike Murach & Associates, Inc. Slide 56