Since prices, descriptions, and pictures of sale items can change, you don’t want to create item description pages by hand. Instead, pages of this sort should be automatically generated. In real life, the data source would probably be a database that is accessed with JDBC (see Chapter 18 of Core Servlets and JavaServer Pages, available in PDF at http://www.moreservlets.com). In this case, a simple data file is used so that the example is short and so that you can run the it without a database.
The item display servlet uses the MVC architecture (see Section 3.8) to display information. First, the servlet (Listing 6.10) reads the itemNum request parameter. If the item number is found, the servlet uses the number as a key into the table of ships (Listing 6.13, a subclass of the more general table shown in Listing 6.14) and creates a SimpleItem object (Listing 6.15) from the result. The servlet then places the SimpleItem in the request object and forwards the request to the ShowItem.jsp page (Listing 6.11, Figure 6-5). The ShowItem.jsp page uses jsp:useBean (Section 3.6) to access the SimpleItem object, then uses that object to look up the item’s description, its cost, and the location of an image file that illustrates it. If, however, the item number is missing, the ShowItem servlet sends the request to Miss-ingItem.jsp (Listing 6.12, Figure 6-6).
Note the importance of using the web.xml file to give the servlet a URL at the top level of the Web app (e.g., http://host/boats/DisplayItem), rather than using the default URL (e.g., http://host/boats/servlet/moreservlets.ShowItem). Because of this simplification, the JSP page need not call getContextPath before using relative URLs. See Section 4.5 (Handling Relative URLs in Web Applications) for details.
package moreservlets; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; /** Servlet that looks up information on an item that is for * sale. Uses the MVC architecture, with either * MissingItem.jsp or ShowItem.jsp doing the presentation. * Used in the boats Web app. */ public class ShowItem extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String itemNum = request.getParameter("itemNum"); String destination; if (itemNum == null) { destination = "/MissingItem.jsp"; } else { destination = "/ShowItem.jsp"; ItemTable shipTable = ShipTable.getShipTable(); SimpleItem item = shipTable.getItem(itemNum); request.setAttribute("item", item); } RequestDispatcher dispatcher = getServletContext().getRequestDispatcher(destination); dispatcher.forward(request, response); } } |
[*] Technically, only the.class file needs to go in this directory.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML> <HEAD> <jsp:useBean id="item" class="moreservlets.SimpleItem" scope="request" /> <TITLE><jsp:getProperty name="item" property="itemNum" /></TITLE> <LINK REL=STYLESHEET HREF="app-styles.css" TYPE="text/css"> </HEAD> <BODY> <TABLE BORDER=5 ALIGN="CENTER"> <TR><TH CLASS="TITLE"> <jsp:getProperty name="item" property="itemNum" /></TABLE> <P> <IMG SRC="<jsp:getProperty name='item' property='imageURL' />" ALIGN="RIGHT"> <H3>Item Number</H2> <jsp:getProperty name="item" property="itemNum" /> <H3>Description</H2> <jsp:getProperty name="item" property="description" /> <H3>Cost</H2> <jsp:getProperty name="item" property="costString" />. A real bargain! <H3>Ordering</H2> <FORM ACTION="DisplayPurchases"> <INPUT TYPE="HIDDEN" NAME="itemNum" VALUE="<jsp:getProperty name='item' property='itemNum' />"> <INPUT TYPE="SUBMIT" VALUE="Submit Order"> </FORM> <%-- Note the lack of "boats" at the front of URI below --%> <%@ taglib uri="/WEB-INF/tlds/count-taglib.tld" prefix="boats" %> <boats:count /> </BODY> </HTML> |
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML> <HEAD> <TITLE>Missing Item Number</TITLE> <LINK REL=STYLESHEET HREF="app-styles.css" TYPE="text/css"> </HEAD> <BODY> <TABLE BORDER=5 ALIGN="CENTER"> <TR><TH CLASS="TITLE">Missing Item Number</TABLE> <P> <H2>Error</H2> <SPAN CLASS="ERROR">You must supply an item number!</SPAN> <%-- Note the lack of "boats" at the front of URI below --%> <%@ taglib uri="/WEB-INF/tlds/count-taglib.tld" prefix="boats" %> <boats:count /> </BODY> </HTML> |
package moreservlets; /** A small collection of ships. Used in the boats Web app. */ public class ShipTable { private static SimpleItem[] ships = { // Yachts new SimpleItem ("BM1", "Base model yacht. Features sauna, two kitchens, " + "and four-car garage. <B>Perfect entry-level " + "yacht for the first-time buyer</B>.", "images/yacht.jpg", 72678922.99), new SimpleItem ("MR1", "Mid-range yacht. Features helipad, bowling alley, " + "and 15 bedrooms. <B>Trade up from a BM1 " + "today!</B>.", "images/yacht.jpg", 145357845.98), new SimpleItem ("HE1", "High-end yacht. Features onboard 18-hole golf " + "course, onboard polo grounds, and ski jump. " + "<B>Bonus: for a limited time only, a mid-sized " + "tropical island country will be included at " + "no extra cost.</B>", "images/yacht.jpg", 7267892299.00), // Oil Tankers new SimpleItem ("Valdez", "Slightly damaged former Alaskan touring boat. " + "<B>Special price won't last long!</B>", "images/tanker.jpg", 9.95), new SimpleItem ("BigBertha", "Tired of cramped quarters on your boat? " + "This roomy model has plenty of space to stretch " + "your legs. <B>10 million gallon onboard " + "swimming pool included!</B>", "images/tanker.jpg", 20000000.00), new SimpleItem ("EcoDisaster", "OK, ok, so this model is not exactly politically " + "correct. <B>But you're not one to pass up " + "a bargain just because of a few " + "<S>Greenpeace</S> pesky demonstrators, " + "are you?</B>.", "images/tanker.jpg", 100000000), // Aircraft Carriers new SimpleItem ("SafeT-1A", "A safe and secure boat, perfect for family " + "vacations. <B>Note:</B> no crew provided. If crew " + "is desired, please see model SafeT-1B.", "images/carrier.jpg", 3167492481.99), new SimpleItem ("SafeT-1B", "Just like the 1A model, but we provide the crew. " + "<B>Note:</B> You must pay the one million dollar " + "annual salary for the crew.", "images/carrier.jpg", 3267492481.99), new SimpleItem ("Lubber-1", "All the comfort of the other models, but without " + "the danger. Realistic simulation provides " + "continuous water sounds. <B>Note:</B> " + "currently located in Siberia. Shipping and " + "handling not included.", "images/carrier.jpg", 152.99) }; private static ItemTable shipTable = new ItemTable(ships); public static ItemTable getShipTable() { return(shipTable); } } |
[*] Technically, only the.class file needs to go in this directory.
package moreservlets; import java.util.HashMap; /** Small class that puts an array of items into a * hash table, making the item number the key. * Used in the boats Web app example. */ public class ItemTable { private HashMap itemMap = new HashMap(); public ItemTable(SimpleItem[] items) { if (items != null) { SimpleItem item; for(int i=0; i<items.length; i++) { item = items[i]; itemMap.put(item.getItemNum(), item); } } } public SimpleItem getItem(String itemNum) { return((SimpleItem)itemMap.get(itemNum)); } } |
[*] Technically, only the.class file needs to go in this directory.
package moreservlets; import java.text.*; /** An item that is for sale. Used in the boats Web app. */ public class SimpleItem { private String itemNum = "Missing item number"; private String description = "Missing description"; private String imageURL = "Missing image URL"; private double cost; private NumberFormat formatter = NumberFormat.getCurrencyInstance(); public SimpleItem(String itemNum, String description, String imageURL, double cost) { setItemNum(itemNum); setDescription(description); setImageURL(imageURL); setCost(cost); } public SimpleItem() {} public String getItemNum() { return(itemNum); } private void setItemNum(String itemNum) { this.itemNum = itemNum; } public String getDescription() { return(description); } private void setDescription(String description) { this.description = description; } public String getImageURL() { return(imageURL); } private void setImageURL(String imageURL) { this.imageURL = imageURL; } public double getCost() { return(cost); } private void setCost(double cost) { this.cost = cost; } public String getCostString() { return(formatter.format(getCost())); } } |
[*] Technically, only the.class file needs to go in this directory.
3.128.198.59