© 2009 Marty Hall Integrating Servlets and JSP: The Model View Controller (MVC) Architecture Originals of Slides and Source Code for Examples: http://courses.coreservlets.com/Course-Materials/csajsp2.html Customized Java EE Training: http://courses.coreservlets.com/ 2 Servlets, JSP, Struts, JSF/MyFaces/Facelets, Ajax, GWT, Spring, Hibernate/JPA, Java 5 & 6. Developed and taught by well-known author and developer. At public venues or onsite at your location. © 2009 Marty Hall For live Java training, please see training courses at http //co rses coreser lets com/ Ser http://courses.coreservlets.com/. Servlets, lets JSP JSP, Str Struts, ts JSF, Ajax, GWT, Java 5, Java 6, Spring, Hibernate, JPA, and customized combinations of topics. p Taught by the author of Core Servlets and JSP, More Servlets and JSP, JSP and this tutorial tutorial. Available at public venues,Customized or customized versions can be held on-site at your Java EE Training: http://courses.coreservlets.com/ Servlets, JSP, Struts, JSF/MyFaces/Facelets, Ajax, GWT, Spring, Hibernate/JPA, Java 5 & 6. organization. Contact [email protected] for details. Developed and taught by well-known author and developer. At public venues or onsite at your location. Agenda • Understanding the benefits of MVC • Using RequestDispatcher to implement MVC • Forwarding requests from servlets to JSP pages • Handling relative URLs • Choosing among different display options • Comparing data-sharing strategies 4 © 2009 Marty Hall MVC Motivation Customized Java EE Training: http://courses.coreservlets.com/ 5 Servlets, JSP, Struts, JSF/MyFaces/Facelets, Ajax, GWT, Spring, Hibernate/JPA, Java 5 & 6. Developed and taught by well-known author and developer. At public venues or onsite at your location. Uses of JSP Constructs Simple p • Application • • • • Complex Application • • Scripting elements calling servlet code directly g elements calling g servlet Scripting code indirectly (by means of utility classes) B Beans Servlet/JSP combo (MVC) MVC with ith JSP expression i language l Custom tags MVC with ith beans, b custom t tags, t and d a framework like Struts or JSF 6 Why Combine Servlets & JSP? • Typical picture: use JSP to make it easier to d develop l and d maintain i i the h HTML HTM content – For simple dynamic code, call servlet code from scripting elements – For slightly more complex applications, use custom classes called from scripting elements – For moderately complex applications, use beans and custom tags • But, But that that’s s not enough – For complex processing, starting with JSP is awkward p the ease of separating p g the real code into separate p – Despite classes, beans, and custom tags, the assumption behind JSP is that a single page gives a single basic look 7 Possibilities for Handling a Single Request • Servlet only. Works well when: – O Output iis a bi binary type. E.g.: E an image i – There is no output. E.g.: you are doing forwarding or redirection as in Search Engine example. – Format/layout of page is highly variable. E.g.: portal. • JSP only. Works well when: – Output p is mostlyy character data. E.g.: g HTML – Format/layout mostly fixed. • Combination (MVC architecture). Needed when: 8 – A single i l requestt will ill result lt in i multiple lti l substantially b t ti ll differentdiff t looking results. – You have a large development team with different team members doing the Web development and the business logic. logic – You perform complicated data processing, but have a relatively fixed layout. MVC Misconceptions • An elaborate framework is necessary – Frameworks are sometimes useful • Struts • JavaServer Faces (JSF) – They are not required! • Implementing MVC with the builtin RequestDispatcher works very well for most simple and moderately complex applications • MVC totally changes your overall system design – You can use MVC for individual requests – Think Thi k off it as the th MVC approach, h nott the th MVC architecture 9 • Also called the Model 2 approach © 2009 Marty Hall Beans Customized Java EE Training: http://courses.coreservlets.com/ 10 Servlets, JSP, Struts, JSF/MyFaces/Facelets, Ajax, GWT, Spring, Hibernate/JPA, Java 5 & 6. Developed and taught by well-known author and developer. At public venues or onsite at your location. Review: Beans • Java classes that follow certain conventions – Must have a zero-argument (empty) constructor • You can satisfy this requirement either by explicitly defining g such a constructor or by y omitting g all constructors • In this version of MVC, it is not required to have zero arg constructor if you only instantiate from Java code – Should have no public instance variables (fields) • I hope you already follow this practice and use accessor methods instead of allowing direct access to fields – Persistent values should be accessed through methods called getXxx and setXxx • If class has method getTitle that returns a String, class i said is id tto h have a St String i property t named d title i l • Boolean properties can use isXxx instead of getXxx 11 Bean Properties: Examples Method Names Property Name Example JSP Usage getFirstName setFirstName firstName <jsp:getProperty … property="firstName"/> <jsp:setProperty … property="firstName"/> ${customer.firstName} isExecutive setExecutive (boolean property) executive <jsp:getProperty … property="executive"/> <jsp:setProperty … property="executive"/> ${customer.executive} getExecutive setExecutive (boolean property) executive <jsp:getProperty … property="executive"/> <jsp:setProperty … property="executive"/> ${customer.executive} getZIP setZIP ZIP <jsp:getProperty … property="ZIP"/> <jsp:setProperty … property="ZIP"/> ${address.ZIP} Note 1: property name does not exist anywhere in your code. It is just a shortcut for the method name. Note 2: property name is derived only from method name. Instance variable name is irrelevant. 12 Example: StringBean package coreservlets; public i class StringBean i { private String message = "No message specified"; public String getMessage() { return(message); } public void setMessage(String message) { this.message i = message; } } • Beans installed in normal Java directory – Eclipse: src/folderMatchingPackage – Deployed: l d …/WEB-INF/classes/folderMatchingPackage / / l /f ld h k • Beans (and utility classes) must always be in packages! 13 © 2009 Marty Hall Basic MVC Design Customized Java EE Training: http://courses.coreservlets.com/ 14 Servlets, JSP, Struts, JSF/MyFaces/Facelets, Ajax, GWT, Spring, Hibernate/JPA, Java 5 & 6. Developed and taught by well-known author and developer. At public venues or onsite at your location. MVC Flow of Control HTML or JSP Java Code (Business Logic) R l Results (beans) Form submit form (Form ACTION matches url-pattern of servlet) Servlet (Store beans in request, session, or application scope) q ( , request.setAttribute("customer", currentCustomer); JSP1 JSP2 JSP3 (Extract data from beans and pput in output) p ) ${customer.firstName} 15 Implementing MVC with RequestDispatcher 1. Define beans to represent the data 2. Use a servlet to handle requests – Servlet reads request parameters, checks for missing and malformed data, data calls business logic logic, etc etc. 3. Populate the beans – The servlet invokes business logic (application-specific (application specific code) or data-access code to obtain the results. Results are placed in the beans that were defined in step 1. 4 St 4. Store the th bean b in i the th request, t session, i or servlet context – 16 The servlet calls setAttribute on the request, request session, session or servlet context objects to store a reference to the beans that represent the results of the request. Implementing MVC with RequestDispatcher (Continued) 5. Forward the request to a JSP page. – The servlet determines which JSP page is appropriate to the situation and uses the forward method of RequestDispatcher to transfer control to that page. 6. Extract the data from the beans. – – – 17 JSP 1.2: the JSP p page g accesses beans with jjsp:useBean p and a scope matching the location of step 4. The page then uses jsp:getProperty to output the bean properties. JSP 22.0: 0: the JSP page uses ${nameFromServlet.property} to output bean properties The JSP page does not create or modify the bean; it merely extracts and displays data that the servlet created. Request Forwarding Example 18 public void doGet(HttpServletRequest request, p p response) p ) HttpServletResponse throws ServletException, IOException { ... // Do business logic and get data String operation = request.getParameter("operation"); if (operation == null) { operation = "unknown"; } String address; if (operation.equals("order")) { address = "/WEB-INF/Order.jsp"; } else if (operation.equals("cancel")) { address = "/WEB-INF/Cancel /WEB-INF/Cancel.jsp jsp"; ; } else { address = "/WEB-INF/UnknownOperation.jsp"; } RequestDispatcher dispatcher = request.getRequestDispatcher(address); dispatcher.forward(request, response); } jsp:useBean in MVC vs. in Standalone JSP Pages • The JSP page should not create the h objects bj – The servlet, not the JSP page, should create all the data objects So, objects. So to guarantee that the JSP page will not create objects, you should use <jsp:useBean ... type="package.Class" /> i instead d off <jsp:useBean ... class="package.Class" /> • The JSP page should not modify the objects –S So, you should h ld use jsp:getProperty j but b not jsp:setProperty. 19 © 2009 Marty Hall Scopes: request, session, and application (ServletContext) Customized Java EE Training: http://courses.coreservlets.com/ 20 Servlets, JSP, Struts, JSF/MyFaces/Facelets, Ajax, GWT, Spring, Hibernate/JPA, Java 5 & 6. Developed and taught by well-known author and developer. At public venues or onsite at your location. Reminder: jsp:useBean Scope Alternatives (JSP 1 1.2 2 Only!) • request – <jsp:useBean id="..." type="..." scope="request" /> • session – <jsp:useBean j B id="..." id " " type="..." " " scope="session" " i " /> / • application – <jsp:useBean id=" id= ..." type= type="..." scope= scope="application" application /> • page – <jsp:useBean id=" id ..." type type="..." scope scope="page" page /> or just <jsp:useBean id="..." type="..." /> – This Thi scope is i nott usedd in i MVC (Model (M d l 2) architecture hit t 21 Request-Based Data Sharing • Servlet ValueObject value = new ValueObject(...); request.setAttribute("key", value); RequestDispatcher dispatcher = request.getRequestDispatcher ("/WEB-INF/SomePage.jsp"); dispatcher.forward(request, response); • JSP 1.2 <jsp:useBean id id="key" key type type="somePackage.ValueObject" somePackage.ValueObject scope="request" /> <jsp:getProperty name="key" property="someProperty" /> • JSP 2 2.0 0 Name chosen by the servlet servlet. ${key.someProperty} Name of accessor method, minus the word "get", with next letter changed to lower case. 22 Request-Based Data Sharing: Simplified Example • Servlet Assume that the Customer constructor handles missing/malformed data. Customer C t myCustomer C t = new Customer(request.getParameter("customerID")); request.setAttribute("customer", myCustomer); RequestDispatcher dispatcher = request.getRequestDispatcher ("/WEB-INF/SomePage.jsp"); dispatcher.forward(request, response); • JSP 1.2 <jsp:useBean j p id="customer" type="somePackage.Customer" yp g scope="request" /> <jsp:getProperty name="customer" property="firstName"/> • JSP 2 2.0 0 ${customer.firstName} 23 Note: the Customer class must have a method called "getFirstName". Session-Based Data Sharing • Servlet ValueObject j value = new ValueObject(...); j HttpSession session = request.getSession(); session.setAttribute("key", value); RequestDispatcher dispatcher = request.getRequestDispatcher ("/WEB-INF/SomePage.jsp"); dispatcher.forward(request, response); • JSP 1.2 <jsp:useBean j p id="key" y type="somePackage.ValueObject" yp g j scope="session" /> <jsp:getProperty name="key" property="someProperty" /> • JSP 2 2.0 0 ${key.someProperty} 24 Session-Based Data Sharing: Variation • Redirect to page instead of forwarding to it – Use U response.sendRedirect dR di instead i d off RequestDispatcher.forward R Di h f d • Distinctions: with sendRedirect: – User sees JSP URL ((user sees only y servlet URL with RequestDispatcher.forward) – Two round trips to client (only one with forward) • Advantage of sendRedirect – User can visit JSP page separately • User can bookmark JSP page • Disadvantages of sendRedirect – Two round trips to server is more expensive – Since user can visit JSP page without going through servlet first, b bean data d might i h not be b available il bl • So, JSP page needs code to detect this situation 25 ServletContext-Based Data Sharing (Rare) • Servlet synchronized(this) { ValueObject value = new ValueObject(...); getServletContext().setAttribute("key", value); Req estDispatcher dispatcher = RequestDispatcher request.getRequestDispatcher ("/WEB-INF/SomePage.jsp"); dispatcher forward(request response); dispatcher.forward(request, } • JSP 1.2 <jsp:useBean j B id="key" id "k " t type="somePackage.ValueObject" " P k V l Obj t" scope="application" /> <jsp:getProperty name="key" property="someProperty" /> • JSP 2.0 ${key.someProperty} 26 Relative URLs in JSP Pages • Issue: – Forwarding with a request dispatcher is transparent to the client. Original URL is only URL browser knows about. • Why does this matter? – What will browser do with tags like the following? <img src="foo.gif" …> <link rel="stylesheet" href my styles.css href="my-styles.css" type="text/css"> <a href="bar.jsp">…</a> – Browser treats addresses as relative to servlet URL 27 © 2009 Marty Hall Examples Customized Java EE Training: http://courses.coreservlets.com/ Servlets, JSP, Struts, JSF/MyFaces/Facelets, Ajax, GWT, Spring, Hibernate/JPA, Java 5 & 6. Developed and taught by well-known author and developer. At public venues or onsite at your location. 28 Applying MVC: Bank Account Balances • Bean – BankCustomer B kC t • Business Logic – BankCustomerLookup • Servlet that populates bean and forwards to appropriate JSP page – Reads customer ID ID, calls BankCustomerLookup BankCustomerLookup’ss data-access code to obtain BankCustomer – Uses current balance to decide on appropriate result page • JSP pages to display results – – – – 29 Negative balance: warning page Regular balance: standard page Hi h bbalance: High l page with ith advertisements d ti t added dd d Unknown customer ID: error page Bank Account Balances: Servlet Code public class ShowBalance extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { BankCustomer customer = BankCustomerLookup.getCustomer (request.getParameter("id")); String address; if (customer == null) { address = "/WEB-INF/bank-account/UnknownCustomer.jsp"; } else if (customer.getBalance() < 0) { address = "/WEB-INF/bank-account/NegativeBalance.jsp"; / /b k / i l j request.setAttribute("badCustomer", customer); } … RequestDispatcher dispatcher = request.getRequestDispatcher(address); dispatcher.forward(request, response); 30 Bank Account Balances: Bean public class BankCustomer { private String p g id, , firstName, , lastName; ; private double balance; public BankCustomer(String id, String firstName, firstName String lastName, double balance) { this.id = id; this.firstName = firstName; this.lastName = lastName; this.balance = balance; } Since the constructor is called from Java only (never from JSP), the requirement for a zero-arg constructor is eliminated. Also, since bean state is set only with constructor, rather than with jsp:setProperty, we can eliminate setter methods and make the class immutable. // Getters for four instance variables. No setters. public i double getBalanceNoSign() i { return(Math.abs(balance)); } 31 } Bank Account Balances: Business Logic public class BankCustomerLookup { private static Map<String,BankCustomer> customers; static { // Populate Map with some sample customers } … public static BankCustomer getCustomer(String id) { return(customers.get(id)); } } 32 Bank Account Balances: Input Form … <fieldset> <legend>Bank Account Balance</legend> <form action="./show-balance"> Customer ID: <input type="text" name="id"><br> <input type="submit" value="Show Balance"> </form> </fieldset> For the servlet, use the address http://host/appName/show-balance that is set via url-pattern in web.xml … 33 Bank Account Balances: JSP 1.2 1 2 Code (Negative Balance) … <BODY> <TABLE BORDER=5 ALIGN="CENTER"> <TR><TH CLASS="TITLE"> We Know Where You Live!</TABLE> <P> <IMG SRC="/bank-support/Club.gif" ALIGN="LEFT"> <jsp:useBean id="badCustomer" type="coreservlets.BankCustomer" scope="request" /> Watch out, <jsp:getProperty name="badCustomer" property="firstName" property= firstName />, /> we know where you live. <P> Pay us the $<jsp:getProperty name="badCustomer" property="balanceNoSign" /> you owe us before it is too late! </BODY></HTML> 34 Bank Account Balances: JSP 2.0 2 0 Code (Negative Balance) … <BODY> <TABLE BORDER=5 ALIGN="CENTER"> <TR><TH CLASS="TITLE"> We Know Where You Live!</TABLE> <P> <IMG SRC="/bank-support/Club.gif" ALIGN="LEFT"> Watch out, ${badCustomer.firstName}, we know where you live. <P> Pay us the $${badCustomer.balanceNoSign} you owe us before b f it is i too t late! l t ! </BODY></HTML> 35 Bank Account Balances: web xml web.xml <?xml version="1.0" encoding="UTF-8"?> <web-app <web app version= version="2.4" 2.4 ...> <!-- Use the URL http://host/app/show-balance instead of http://host/app/servlet/coreservlets.ShowBalance --> <servlet> <servlet-name>ShowBalance</servlet-name> <servlet-class>coreservlets.ShowBalance</servlet-class> </servlet> <servlet-mapping> l i <servlet-name>ShowBalance</servlet-name> <url-pattern>/show-balance</url-pattern> </servlet-mapping> ... </web-app> 36 Bank Account Balances: Results 37 Comparing Data-Sharing Approaches: Request • Goal – Display a random number to the user • Type of sharing – Each request should result in a new number, so requestbased sharingg is appropriate. pp p 38 Request-Based Sharing: Bean package coreservlets; public class NumberBean { private double num = 0; public NumberBean(double number) { this.num = number; } public double getNumber() { etu ( u ); return(num); } } The property name in JSP will be “number”. number . The property name is derived from the method name, not from the instance variable name. Also note the lack of a corresponding setter. 39 Request-Based Sharing: Servlet public class RandomNumberServlet extends HttpServlet { public void doGet(HttpServletRequest request, request HttpServletResponse response) throws ServletException, IOException { NumberBean bean = RanUtils.getRandomNum(request.getParameter("range")); request.setAttribute("randomNum", bean); String g address = "/WEB-INF/mvc-sharing/RandomNum.jsp"; / / g/ j p ; RequestDispatcher dispatcher = request.getRequestDispatcher(address); dispatcher.forward(request, response); } } 40 Request-Based Sharing: Business Logic public class RanUtils { public static NumberBean getRandomNum(String rangeString) { double range; try { range = Double.parseDouble(rangeString); } catch(Exception e) { range = 10.0; } return(new NumberBean(Math.random() * range)); } } 41 Request-Based Sharing: URL Pattern (web (web.xml) xml) ... <servlet> <servlet-name>RandomNumberServlet</servlet-name> <servlet-class> coreservlets.RandomNumberServlet </servlet-class> </servlet> <servlet mapping> <servlet-mapping> <servlet-name>RandomNumberServlet</servlet-name> <url-pattern>/random-number</url-pattern> /se et app g </servlet-mapping> ... 42 Request-Based Sharing: Input Form ... <fieldset> <legend>Random Number</legend> <form action="./random-number"> Range: <input type= type="text" text name= name="range"><br/> range ><br/> <input type="submit" value="Show Number"> </form> </fieldset> ... 43 Request-Based Sharing: JSP 1.2 … <BODY> <jsp:useBean id="randomNum" type="coreservlets.NumberBean" scope="request" scope= request /> <H2>Random Number: <jsp:getProperty name="randomNum" property="number" property number /> </H2> </BODY></HTML> 44 Request-Based Sharing: JSP 2.0 … <BODY> <H2>Random Number: ${randomNum.number}</H2> </BODY></HTML> 45 Request-Based Sharing: Results 46 Comparing Data-Sharing Approaches: Session • Goal – Display users’ first and last names. – If the users fail to tell us their name, we want to use whatever name they gave us previously. previously – If the users do not explicitly specify a name and no previous name is found, a warning should be displayed. • Type of sharing –D Data iis storedd for f eachh client, li so session-based i b d sharing h i is i appropriate. 47 Session-Based Sharing: Bean public class NameBean implements Serializable { private String firstName = "Missing first name"; private String lastName = "Missing last name"; public String getFirstName() { return(firstName); } public void setFirstName(String firstName) { if (!isMissing(firstName)) { this.firstName = firstName; } } ... // getLastName, setLastName private boolean isMissing(String value) { return((value == null) || (value.trim().equals(""))); } } 48 Session-Based Sharing: Servlet 49 public class RegistrationServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { HttpSession session = request.getSession(); synchronized(session) { NameBean nameBean = (NameBean)session.getAttribute("name"); if (nameBean == null) { (); nameBean = new NameBean(); session.setAttribute("name", nameBean); } nameBean.setFirstName(request.getParameter("firstName")); nameBean.setLastName(request.getParameter( lastName )); nameBean.setLastName(request.getParameter("lastName")); String address = "/WEB-INF/mvc-sharing/ShowName.jsp"; RequestDispatcher dispatcher = request.getRequestDispatcher(address); dispatcher forward(request response); dispatcher.forward(request, } } } Session-Based Sharing: JSP 1.2 … <BODY> <H1>Thanks for Registering</H1> <jsp:useBean id="name" type= coreservlets.NameBean type="coreservlets.NameBean" scope="session" /> <H2>First Name: <jsp:getProperty name name="name" name property="firstName" /></H2> <H2>Last Name: jsp:get ope ty name="name" a e a e <jsp:getProperty property="lastName" /></H2> </BODY></HTML> 50 Session-Based Sharing: JSP 2.0 … <BODY> <H1>Thanks for Registering</H1> <H2>First Name: ${name.firstName}</H2> <H2>Last Name: ${name.lastName}</H2> </BODY></HTML> 51 Session-Based Sharing: Results Note: url-pattern url pattern in web.xml is "register". 52 Comparing Data-Sharing Approaches: ServletContext • Goal – Display a prime number of a specified length. – If the user fails to tell us the desired length, we want to use whatever prime number we most recently computed for any user. • Type of sharing – Data is shared among multiple clients, so applicationbased sharing is appropriate appropriate. 53 ServletContext-Based Sharing: Bean package coreservlets; import p java.math.BigInteger; j g g ; public class PrimeBean { private BigInteger prime; public PrimeBean(String lengthString) { int length = 150; try t y { length = Integer.parseInt(lengthString); } catch(NumberFormatException nfe) {} this.prime = Primes.nextPrime(Primes.random(length)); } public BigInteger getPrime() { return(prime); } … 54 } ServletContext-Based Sharing: Servlet public class PrimeServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String length = request.getParameter("primeLength"); ServletContext context = getServletContext(); synchronized(this) { if ((context.getAttribute("primeBean") == null) || (length != null)) { PrimeBean primeBean = new PrimeBean(length); context.setAttribute("primeBean", primeBean); } String address = "/WEB-INF/mvc-sharing/ShowPrime.jsp"; / / h i / h i j RequestDispatcher dispatcher = request.getRequestDispatcher(address); dispatcher.forward(request, response); } } } 55 ServletContext-Based Sharing: JSP 1 1.2 2 … <BODY> <H1>A Prime Number</H1> <jsp:useBean id="primeBean" type= coreservlets.PrimeBean type="coreservlets.PrimeBean" scope="application" /> <jsp:getProperty name="primeBean" property="prime" property prime /> </BODY></HTML> 56 ServletContext-Based Sharing: JSP 2 2.0 0 … <BODY> <H1>A Prime Number</H1> ${primeBean.prime} </BODY></HTML> 57 ServletContext-Based Sharing: Results Note: url-pattern in web.xml is "prime". 58 © 2009 Marty Hall Forwarding and g Including Customized Java EE Training: http://courses.coreservlets.com/ 59 Servlets, JSP, Struts, JSF/MyFaces/Facelets, Ajax, GWT, Spring, Hibernate/JPA, Java 5 & 6. Developed and taught by well-known author and developer. At public venues or onsite at your location. Forwarding from JSP Pages <% String destination; if (Math (Math.random() random() > 0.5) 0 5) { destination = "/examples/page1.jsp"; } else { destination = "/examples/page2.jsp"; /examples/page2.jsp ; } %> <jsp:forward page page="<%= <% destination %> %>" /> • Legal, Legal but bad idea – Business and control logic belongs in servlets – Keepp JSP focused on ppresentation 60 Including Pages Instead of Forwarding to Them • With the forward method of RequestDispatcher: – New page generates all of the output g ppage g cannot ggenerate any y output p – Original • With the include method of RequestDispatcher: –O Output t t can be b generated t d by b multiple lti l pages – Original page can generate output before and after the included page – Original servlet does not see the output of the included page (for this, see later topic on servlet/JSP filters) – Applications pp • Portal-like applications (see first example) • Setting content type for output (see second example) 61 Using RequestDispatcher.include: portals response.setContentType("text/html"); String firstTable, secondTable, thirdTable; if (someCondition) di i { firstTable = "/WEB-INF/Sports-Scores.jsp"; secondTable = "/WEB-INF/Stock-Prices.jsp"; thirdTable = "/WEB-INF/Weather.jsp"; } else if (...) ( ) { ... } RequestDispatcher dispatcher = request.getRequestDispatcher("/WEB-INF/Header.jsp"); dispatcher.include(request, response); dispatcher = request.getRequestDispatcher(firstTable); dispatcher.include(request, response); dispatcher = request.getRequestDispatcher(secondTable); dispatcher.include(request, response); dispatcher = request.getRequestDispatcher(thirdTable); dispatcher.include(request, response); dispatcher = request.getRequestDispatcher("/WEB-INF/Footer.jsp"); dispatcher.include(request, response); 62 Using RequestDispatcher.include: Setting Content Content-Type Type of Output // From Ajax example public void doGet(...) p ( ) ... { ... if ("xml".equals(format)) { response.setContentType("text/xml"); outputPage = "/WEB-INF/results/cities-xml.jsp"; "/WEB INF/results/cities xml jsp"; } else if ("json".equals(format)) { response.setContentType("text/javascript"); outputPage = "/WEB-INF/results/cities-json.jsp"; } else { response.setContentType("text/plain"); outputPage = "/WEB-INF/results/cities-string.jsp"; } RequestDispatcher dispatcher = request.getRequestDispatcher(outputPage); dispatcher.include(request, response); } 63 cities-xml.jsp <?xml version="1.0" encoding="UTF-8"?> <cities> <city> <name>${cities[0].name}</name> <time>${cities[0].shortTime}</time> <population>${cities[0].population}</population> </city> ... </cities> • Notes 64 – Because I use .jsp (not .jspx) and classic JSP syntax, the default content-type is text/html – I could use <%@ page contentType contentType="text/html" text/html %> here here, but it is more convenient to do it in calling servlet and keep this page simple and focused on presentation Summary • Use MVC (Model 2) approach when: – One O submission b i i will ill result l in i more than h one basic b i look l k – Several pages have substantial common processing • Architecture – A servlet answers the original request – Servlet does the real work & stores results in beans • Beans stored in HttpServletRequest, HttpSession, or ServletContext – Servlet forwards to JSP page via forward method of RequestDispatcher – JSP page reads data from beans 65 • JSP 1 1.2: 2: jsp:useBean with appropriate scope (request (request, session, or application) plus jsp:getProperty • JSP 2.x: ${beanName.propertyName} © 2009 Marty Hall Questions? Customized Java EE Training: http://courses.coreservlets.com/ 66 Servlets, JSP, Struts, JSF/MyFaces/Facelets, Ajax, GWT, Spring, Hibernate/JPA, Java 5 & 6. Developed and taught by well-known author and developer. At public venues or onsite at your location.
© Copyright 2026 Paperzz