1.06k likes | 1.31k Views
Chapter 16 — Server-side Java Programming. Outline 16.1 Introduction 16.2 Cocoon 16.3 Extensible Server Pages (XSP) 16.4 Case Study: A Wireless Online Bookstore 16.5 Jakarta Tomcat Setup 16.6 WAP and WML: Client-side Documents 16.7 Java Servlets. 16.1 Introduction. XML to deliver Web content
E N D
Chapter 16 — Server-side Java Programming Outline16.1 Introduction16.2 Cocoon16.3 Extensible Server Pages (XSP)16.4 Case Study: A Wireless Online Bookstore16.5 Jakarta Tomcat Setup16.6 WAP and WML: Client-side Documents16.7 Java Servlets
16.1 Introduction • XML to deliver Web content • Apache’s Cocoon • Extensible Server Pages (XSP) • Java servlets
16.2 Cocoon • Cocoon • Use XML to deliver same content to various client types • Without creating multiple Web-site versions • Separate Web-publishing process into three steps • XML creation • XML processing • XSL rendering
1 <?xml version ="1.0"?> Instruct Cocoon to use its XSLT processor to process document before delivering it to client 2 <?cocoon-process type ="xslt"?> 3 <?xml-stylesheet href = "welcome.xsl"type ="text/xsl"?> Specify welcome.xsl as default style sheet to use with XSLT processor 4 <?xml-stylesheet href ="welcome-wml.xsl" Instruct XSLT processor to use welcome-wml.xsl for WAP devices 5 type ="text/xsl"media ="wap"?> 6 7 <!-- Fig. 16.1 : welcome.xml --> 8 9 <myMessage> 10 <message>Welcome to XML!</message> 11 </myMessage> Fig. 16.1 XML document to be process by Cocoon.Line 2Line 3Lines 4-5
1 <?xml version ="1.0"?> welcome.xsl transforms XML content into HTML document 2 3 <!-- Fig. 16.3 : welcome.xsl --> 4 5 <xsl:stylesheet 6 xmlns:xsl ="http://www.w3.org/1999/XSL/Transform" 7 version ="1.0"> 8 9 <xsl:template match ="myMessage"> 10 <html> 11 <head> 12 <title><xsl:value-of select ="message"/></title> 13 </head> 14 15 <body bgcolor ="cyan"> 16 <xsl:apply-templates select ="message"/> 17 <p>This page has been transformed 18 from XML into HTML by Cocoon’s XSLT processor. 19 </p> 20 </body> 21 22 </html> 23 </xsl:template> 24 25 <xsl:template match ="message"> 26 <h1> 27 <xsl:apply-templates/> 28 </h1> 29 </xsl:template> 30 </xsl:stylesheet> Fig. 16.3 Style sheet to render welcome.xml.Line 3
1 <?xml version = "1.0"?> welcome-wml.xsl transforms XML content in WML for display on wireless devices 2 3 <!-- Fig. 16.4 : welcome-wml.xsl --> 4 5 <xsl:stylesheet 6 xmlns:xsl = "http://www.w3.org/1999/XSL/Transform" WML places multiple pages (cards) of content into a deck 7 version ="1.0"> 8 Paragraph elements 9 <xsl:template match ="myMessage"> 10 <xsl:processing-instruction name = "cocoon-format"> 11 type = "text/wml" 12 </xsl:processing-instruction> 13 14 <wml> 15 <card> 16 17 <p> 18 <xsl:value-of select ="message"/> 19 </p> 20 21 <p> 22 This page has been transformed 23 from XML into WML by Cocoon’s XSLT processor. 24 </p> 25 26 </card> 27 </wml> 28 </xsl:template> 29 </xsl:stylesheet> Fig. 16.4 welcome-wml.xsl.Line 3Line 15Lines 17-24
Courtesy of Phone.com, Inc. Output from Fig. 16.4
16.3 Extensible Server Pages (XSP) • Extensible Server Pages (XSP) • Allows code to be marked up for server to process • Example: • Client is sent HTML page with form asking favorite color • HTML page is result of XSLT • Process survey.xml with survey.xsl • User sends POST request to server to submit color • Server sends XSP document (response.xml)
1 <?xml version ="1.0"?> 2 <?cocoon-process type ="xslt"?> 3 <?xml-stylesheet href ="survey.xsl"type ="text/xsl"?> 4 5 <!-- Fig. 16.6 : survey.xml --> 6 7 <page title ="Color survey"> 8 <color>Red</color> 9 <color>Blue</color> 10 <color>Green</color> 11 <color>Yellow</color> 12 <color>Purple</color> 13 </page> Fig. 16.6 XML document with color choices.
14 <?xml version = "1.0"?> 15 16 <!-- Fig. 16.7 : survey.xsl --> 17 18 <xsl:stylesheet 19 xmlns:xsl = "http://www.w3.org/1999/XSL/Transform" 20 version ="1.0"> 21 22 <xsl:template match ="page"> 23 <html> 24 <head> 25 <title> 26 <xsl:value-of select ="@title"/> 27 </title> 28 </head> Fig. 16.7 Style sheet to present color choices as HTML.
29 <body bgcolor ="cyan"> 30 <h1> 31 <xsl:value-of select = "@title"/> 32 </h1> 33 <b>What is your favorite color?</b> 34 <form method ="post" 35 action = 36 "http://127.0.0.1:8080/CocoonEx/response.xml"> 37 38 <xsl:apply-templates select ="color"/> 39 <input type ="submit" value = "Submit"/> 40 </form> 41 </body> 42 </html> 43 </xsl:template> 44 45 <xsl:template match ="color"> 46 <input type ="radio"name ="color"> 47 <xsl:attribute name ="value"> 48 <xsl:value-of select ="."/> 49 </xsl:attribute> 50 </input> 51 <xsl:value-of select ="."/> 52 <br/> 53 </xsl:template> 54 </xsl:stylesheet> Fig. 16.7 Style sheet to present color choices as HTML (Part 2).
55 <?xml version ="1.0"?> Process client’s POST request 56 <?cocoon-process type ="xsp"?> 57 <?cocoon-process type = "xslt"?> Use Java as programming language 58 <?xml-stylesheet href ="response.xsl"type ="text/xsl"?> Import packages that allow for inputting and outputting XML document 59 60 <!-- Fig. 16.8 : response.xml --> Embed all Java code in xsp:logic element 61 62 <xsp:page language ="java" 63 xmlns:xsp ="http://www.apache.org/1999/XSP/Core"> Method inputColors uses DOMParser to parse colors.xml and create Document colors 64 65 <xsp:structure> 66 <xsp:include>java.text.*</xsp:include> 67 <xsp:include>org.apache.xerces.parsers.*</xsp:include> 68 <xsp:include>org.apache.xml.serialize.*</xsp:include> 69 </xsp:structure> 70 71 <xsp:logic> 72 private Document colors = inputColors(); 73 privateint total = Integer.parseInt( 74 colors.getDocumentElement().getAttribute( "total" ) ); 75 NodeList colorElements = 76 colors.getDocumentElement(). 77 getElementsByTagName( "color" ); 78 79 private Document inputColors() 80 { 81 try { 82 InputSource input = 83 new InputSource( new FileInputStream( 84 "../webapps/CocoonEx/colors.xml" ) ); 85 DOMParser domParser = new DOMParser(); Fig. 16.8 XML document containing the logic to retrieve survey statistics.Line 60Line 62Lines 65-69Line 71Line 79
86 87 domParser.parse( input ); Method getColorElement returns color element corresponding to parameter String color 88 return domParser.getDocument(); 89 } 90 catch ( Exception e ) { 91 e.printStackTrace(); 92 returnnull; 93 } Method getPercentage calculates percentage of votes the specified color has received 94 } 95 96 private Element getColorElement( String color ) 97 { 98 for ( int i = 0; i < colorElements.getLength(); i++ ) { 99 Element current = ( Element ) colorElements.item( i ); 100 101 if ( current.getAttribute( "name" ).equals( color ) ) 102 return current; 103 104 } 105 returnnull; 106 } 107 108 private String getPercentage( String color ) 109 { 110 if ( total == 0 ) 111 return "No entries yet"; 112 else { 113 int votes = Integer.parseInt( 114 getColorElement( color ).getAttribute( "votes" ) ); 115 double percentage = 100.0 * votes / total; Fig. 16.8 XML document containing the logic to retrieve survey statistics(Part 2).Line 96Line 108
116 117 return 118 new DecimalFormat( "#0.00" ).format( percentage ) Method updateSurvey updates colors.xml to reflect client’s vote 119 + "%"; 120 } 121 } 122 123 privatevoid updateSurvey( String voteColor ) 124 { 125 // update total number of votes 126 ++total; 127 colors.getDocumentElement().setAttribute( 128 "total", Integer.toString( total ) ); 129 130 // update number of votes for voted color 131 Element votedColorElement = getColorElement( voteColor ); 132 int votes = Integer.parseInt( 133 votedColorElement.getAttribute( "votes" ) ) + 1; 134 135 votedColorElement.setAttribute( 136 "votes", Integer.toString( votes ) ); 137 138 // save XML file 139 try { 140 XMLSerializer serializer = new XMLSerializer( 141 new FileOutputStream( 142 "../webapps/CocoonEx/colors.xml" ), 143 null ); 144 145 serializer.serialize( colors ); 146 } Fig. 16.8 XML document containing the logic to retrieve survey statistics(Part 3).Line 123
147 catch ( Exception e ) { 148 e.printStackTrace(); Create root element survey as target of XSP processing 149 } 150 } 151 </xsp:logic> 152 153 <survey title ="Color survey"> 154 <xsp:logic> Embed Java code to create child elements of root element survey 155 String vote = request.getParameter( "color" ); 156 updateSurvey( vote ); 157 158 // create total element to hold total number of votes 159 <total><xsp:expr>total</xsp:expr></total> 160 161 // create a new color element for each color 162 for ( int i = 0; i < colorElements.getLength(); i++ ) { 163 Element current = ( Element ) colorElements.item( i ); 164 String colorName = current.getAttribute( "name" ); 165 <color> 166 <xsp:attribute name ="value"> 167 <xsp:expr>colorName</xsp:expr> 168 </xsp:attribute> 169 <xsp:attribute name ="percentage"> 170 <xsp:expr>getPercentage( colorName )</xsp:expr> 171 </xsp:attribute> 172 </color> 173 } 174 </xsp:logic> 175 </survey> 176 </xsp:page> Fig. 16.8 XML document containing the logic to retrieve survey statistics(Part 4).Line 153Lines 154-174
177 <?xml version = "1.0"?> 178 179 <!-- Fig. 16.09 : response.xsl --> 180 181 <xsl:stylesheet 182 xmlns:xsl ="http://www.w3.org/1999/XSL/Transform" 183 version ="1.0"> 184 185 <xsl:template match ="survey"> 186 <html> 187 <head> 188 <title> 189 <xsl:value-of select ="@title"/> 190 </title> 191 </head> 192 <body bgcolor ="cyan"> 193 <h1> 194 <xsl:value-of select = "@title"/> 195 </h1> 196 <table border ="1"> 197 <thead> 198 <td>Color</td> 199 <td>Percentage</td> 200 </thead> 201 <xsl:apply-templates/> 202 </table> 203 </body> 204 </html> 205 </xsl:template> 206 Fig. 16.9 response.xsl.
207 <xsl:template match = "total"> 208 <p>Total votes so far: 209 <xsl:value-of select ="."/> 210 </p> 211 </xsl:template> 212 213 <xsl:template match ="color"> 214 <tr> 215 <td><xsl:value-of select ="@value"/></td> 216 <td><xsl:value-of select ="@percentage"/></td> 217 </tr> 218 </xsl:template> 219 </xsl:stylesheet> Fig. 16.9 response.xsl(Part 2).
16.4 Case Study: A Wireless Online Bookstore • Wireless online bookstore • Use XML and XSL with Java servlets • Use Wireless Applications Protocol (WAP) • Wireless Markup Language (WML) • Multi-tier architecture • Data tier maintains information • Middle tier implements business logic and presentation logic • Client tier provides user interface
Fig. 16.10 Three-tier architecture for the Deitel wireless book store.
Fig. 16.12 Server-side components for wireless bookstore (cont).
16.5 Jakarta Tomcat Setup • Jakarta Tomcat • Reference implementation for Java servlets • Servlets run in servlet container in Web server • Setup • Java 2 • Jakarta • Databases (cart.mdb and catalog.mdb) • XSL files • Xalan XSLT processor • UP.SDK (UP.Simulator)
16.6 WAP and WML: Client-side Documents • Client side consists of WML documents • WML • application of XML • Places multiple pages of content in deck (WML document) • Each page is stored in card element
1 <?xml version ="1.0"?> index.wml allows user to choose to log in to store or to create account 2 <!-- Fig. 16.13: index.wml --> 3 <!-- Home page for bookstore --> WAP Forum defines document DTD 4 <!DOCTYPE wml PUBLIC"-//WAPFORUM//DTD WML 1.1//EN" Store page in card element 5 "http://www.wapforum.org/DTD/wml_1.1.xml"> Paragraph elements 6 <wml> Browser displays login.wml if user selects option 7 <card> 8 <p>Welcome to Deitel Wireless shopping.</p> Browser displays newuser.wml if user selects option 9 <p> 10 <select> 11 <option onpick ="login.wml"> 12 Log in 13 </option> 14 <option onpick ="newuser.wml"> 15 New account 16 </option> 17 </select> 18 </p> 19 </card> 20 </wml> Fig. 16.13 Code listing for index.wml.Line 2Lines 4-5Line 7Lines 8-9Lines 11-13Lines 14-16
Courtesy of Phone.com, Inc. Output from Fig. 16.13
1 <?xml version = "1.0"?> 2 <!-- Fig. 16.14: login.wml --> 3 <!-- Prompts for username and password --> 4 <!DOCTYPE wml PUBLIC"-//WAPFORUM//DTD WML 1.1//EN" Declare variable param1 for storing user’s login name Continue to pass card when user presses accept key 5 "http://www.wapforum.org/DTD/wml_1.1.xml"> 6 <wml> 7 <card> 8 <onevent type ="onenterforward"> Prompt user for username Declare pass card 9 10 <refresh> 11 <setvar name ="param1"value =""/> 12 </refresh> 13 14 </onevent> 15 16 <do type="accept"> 17 <go href="#pass"/> 18 </do> 19 20 <p>Enter your name and password to login</p> 21 <p> 22 Name: 23 <input name ="param1"format ="mmmmm*m"type ="text" 24 maxlength ="10"/> 25 </p> 26 </card> 27 28 <card id ="pass"> 29 <onevent type ="onenterforward"> 30 Fig. 16.14 Code listing for login.wml.Lines 10-12Lines 16-18Lines 23-24Line 28
31 <refresh> 32 <setvar name = "param2"value =""/> Redirect user to LoginServlet, which reads username and password to authenticate user 33 </refresh> 34 35 </onevent> 36 37 <do type ="accept"> 38 <go href ="cartXML.LoginServlet?action=login" 39 method ="post"> 40 41 <postfield name ="param2"value ="$(param2)"/> 42 <postfield name ="param1"value ="$(param1)"/> 43 44 </go> 45 </do> 46 <p>Password: 47 48 <input name ="param2"format = "mmmmm*m" 49 type ="password" maxlength ="10"/> 50 51 </p> 52 </card> 53 </wml> Fig. 16.14 Code listing for login.wml (Part 2).Line 38
Output from Fig. 16.14 • Courtesy of Phone.com, Inc.
1 <?xml version = "1.0"?> Displayed if user selects option “New account” from index.wml 2 3 <!-- Fig. 16.15: newuser.wml --> 4 <!-- Prompts for username and password --> 5 6 <!DOCTYPE wml PUBLIC"-//WAPFORUM//DTD WML 1.1//EN" 7 "http://www.wapforum.org/DTD/wml_1.1.xml"> 8 <wml> Prompt user to enter new username 9 <card> 10 <onevent type ="onenterforward"> 11 12 <refresh> 13 <setvar name ="param1"value =""/> 14 </refresh> 15 16 </onevent> 17 <do type ="accept"> 18 <go href ="#pass1"/> 19 </do> 20 <p>Please enter a name and password to create your 21 account</p> 22 <p> 23 Name(5-10 characters): 24 <input name ="param1"format = "mmmmm*m"type ="text" 25 maxlength = "10"/> 26 </p> 27 </card> 28 29 <card id ="pass1"> 30 <onevent type = "onenterforward"> Fig. 16.15 Code listing for newuser.wml.Line 3Lines 24-25
31 32 <refresh> 33 <setvar name = "param2" value = ""/> 34 </refresh> 35 36 </onevent> 37 38 <do type = "accept"> Prompt user to enter new password 39 <go href = "#pass2"/> 40 </do> 41 42 <p>Password(5-10 characters): 43 <input name = "param2" format = "mmmmm*m" 44 type = "password" maxlength = "10"/> 45 </p> 46 </card> 47 48 <card id = "pass2"> 49 <onevent type = "onenterforward"> 50 51 <refresh> 52 <setvar name ="param3"value = ""/> 53 </refresh> 54 55 </onevent> 56 <do type = "accept"> 57 <go href= 58 "cartXML.LoginServlet?action=newuser" 59 method = "post"> 60 Fig. 16.15 Code listing for newuser.wml(Part 2).Lines 43-44
61 <postfield name = "param2" value = "$(param2)"/> 62 <postfield name = "param1" value = "$(param1)"/> 63 <postfield name = "param3" value = "$(param3)"/> 64 65 </go> 66 </do> 67 <p>Verify Password: 68 Prompt user to verify password 69 <input name = "param3" format = "mmmmm*m" 70 type = "password" maxlength = "10"/> 71 72 </p> 73 </card> 74 </wml> Fig. 16.15 Code listing for newuser.wml(Part 3).Lines 69-70
Courtesy of Phone.com, Inc. Output from Fig. 16.15
16.7 Java Servlets • Java servlets • Provide business logic and presentation logic • Middle tier • Receives requests from clients • Connects to database
1 // Fig. 16.16: Database.java 2 // Queries a database Class Database is used to connect to database and execute queries to retrieve and update data 3 package cartXML; 4 importjava.sql.*; 5 Initialize URL where database is located, username and password 6 public class Database { 7 private Connection connection; 8 private static String username; Load database driver from ODBC databases 9 private static String password; 10 private static String url; Establish connection to database 11 private Statement statement; 12 13 public Database( String url, String username, 14 String password ) 15 { 16 this.url = url; 17 this.username = username; 18 this.password = password; 19 } 20 21 public booleanconnect() 22 { 23 try { 24 Class.forName( "sun.jdbc.odbc.JdbcOdbcDriver" ); 25 connection = DriverManager.getConnection( url, username, 26 password ); 27 return true; 28 } 29 catch ( Exception ex ) { 30 ex.printStackTrace(); 31 } Fig. 16.6 Code listing for Database.java.Line 6Lines 13-19Line 24Lines 25-26
32 33 return false; Make query to database and store returned data in ResultSet 34 } 35 36 public ResultSet get( String query ) 37 { 38 try { Update database with new record 39 statement = connection.createStatement(); 40 ResultSet rs = statement.executeQuery( query ); 41 return rs; 42 } 43 catch ( SQLException sqle ) { 44 return null; 45 } 46 } 47 48 public boolean update( String query ) 49 { 50 try { 51 statement = connection.createStatement(); 52 statement.executeUpdate( query ); 53 return true; 54 } 55 catch ( SQLException sqle ) { 56 return false; 57 } 58 } 59 Fig. 16.6 Code listing for Database.java (Part 2).Lines 36-46Lines 48-58
60 public boolean shutDown() 61 { Close connection to database 62 try { 63 connection.close(); 64 return true; 65 } 66 catch ( SQLException sqlex ) { 67 return false; 68 } 69 } 70 } Fig. 16.6 Code listing for Database.java (Part 3).Line 63
1 // Fig. 16.17: ShoppingCart.java 2 // Shopping cart 3 package cartXML; Class ShoppingCart represents shopping cart for user 4 import javax.servlet.http.*; 5 import java.text.*; HttpSessionBindingListener allows user to retrieve previous shopping carts 6 import java.io.*; 7 import org.w3c.dom.*; Methods implementing HttpSessionBindingListener 8 import java.util.*; 9 10 public class ShoppingCart implements HttpSessionBindingListener { Save shopping-cart information when user exits 11 private Vector books; 12 private String username; 13 private Database database; 14 15 public ShoppingCart() 16 { books = new Vector( 5 ); } 17 18 public void valueBound( HttpSessionBindingEvent e ) {} 19 20 public void valueUnbound( HttpSessionBindingEvent e ) 21 { 22 if ( username == null ) // if username is null, exit 23 return; 24 25 save(); 26 } 27 Fig. 16.17 Code listing for Shopping-Cart.java.Line 10Line 10Lines 18-20Line 25
28 public void save() 29 { 30 database = new Database( "jdbc:odbc:cart", "anonymous", Save shopping-cart information (store information in database) 31 "guest" ); 32 database.connect(); 33 delete( username ); 34 Delete user from database 35 for ( int i = 0; i < getLength(); i++ ) { 36 Book b = ( Book ) books.elementAt( i ); 37 String productID = b.getProductID(); Insert user’s name, ID of product desired and quantity of product 38 int quantity = b.getQuantity(); 39 40 insert( username, productID, String.valueOf( quantity ) ); 41 } 42 43 database.shutDown(); 44 } 45 46 public void delete( String username ) 47 { 48 String query = "DELETE * FROM Carts WHERE username = '" 49 + username + "'"; 50 51 database.update( query ); 52 } 53 54 public void insert( String username, String productID, 55 String quantity ) 56 { 57 Date today; 58 String date; 59 DateFormat dateFormatter; Fig. 16.17 Code listing for Shopping-Cart.java (Part 2).Lines 28-44Lines 46-52Lines 54-71
60 61 dateFormatter = DateFormat.getDateInstance( 62 DateFormat.DEFAULT ); 63 today = new Date(); 64 date = dateFormatter.format(today); Add book to Vectorbooks (which stores books) 65 Remove book from Vectorbooks 66 String query = "INSERT INTO Carts ( username, productID, " Set quantity of specified book 67 + "quantity, dateCreated ) VALUES ('" + username + "'," 68 + productID + "," + quantity + ",'" + date + "' )"; 69 70 database.update( query ); 71 } 72 73 public void add( Book b ) 74 { books.addElement( b ); } 75 76 public void remove( int i ) 77 { books.removeElementAt( i ); } 78 79 public void setQuantity( int i, int quantity ) 80 { 81 Book b = ( Book ) books.elementAt( i ); 82 83 b.setQuantity( quantity ); 84 } 85 86 public String getUsername() 87 { return username; } 88 89 public void setUsername( String s ) 90 { username = s; } Fig. 16.17 Code listing for Shopping-Cart.java (Part 3).Lines 73-74Lines 76-77Lines 79-84
91 Get price of specified book Return quantity associated with specified book Return product ID of specified book Return description of specified book 92 public String[] getDescription( int i ) 93 { 94 Book b = ( Book ) books.elementAt( i ); 95 96 return b.getDescription(); 97 } 98 99 public String getProductID( int i ) 100 { 101 Book b = ( Book ) books.elementAt( i ); 102 103 return b.getProductID(); 104 } 105 106 public int getQuantity( int i ) 107 { 108 Book b = ( Book ) books.elementAt( i ); 109 110 return b.getQuantity(); 111 } 112 113 public double getPrice( int i ) 114 { 115 Book b = ( Book ) books.elementAt( i ); 116 117 return b.getPrice(); 118 } 119 Fig. 16.17 Code listing for Shopping-Cart.java (Part 4).Lines 92-97Lines 99-104Lines 106-111Lines 113-118
120 public String getFormattedPrice( int i ) Get price (formatted in dollars and cents) of specified book 121 { 122 Book b = ( Book ) books.elementAt( i ); 123 double price = b.getPrice(); 124 NumberFormat priceFormatter = 125 NumberFormat.getCurrencyInstance(); 126 String formattedPrice = priceFormatter.format( price ); 127 128 return formattedPrice; 129 } 130 131 publicint getLength() 132 { return books.size(); } 133 134 // returns the index of the vector if productID is found in 135 // cart, -1 otherwise 136 public int contains( String id ) 137 { 138 139 for ( int i = 0; i < getLength(); i++ ) { 140 Book b = ( Book ) books.elementAt( i ); 141 String bookID = b.getProductID(); 142 143 if ( bookID != null && bookID.equals( id ) ) 144 return i; 145 } 146 147 return -1; 148 } 149 Fig. 16.17 Code listing for Shopping-Cart.java (Part 5).Lines 120-129
150 public String getTotal() Get total prices (formatted in dollars and cents) of all books in shopping cart 151 { 152 double total = 0; 153 154 for ( int i = 0; i < getLength(); i++ ) 155 total += getPrice( i ) * getQuantity( i ); Called from ViewCartServlet when user request to view shopping cart 156 157 NumberFormat priceFormatter = Produce XML that describes shopping cart 158 NumberFormat.getCurrencyInstance(); 159 String formattedTotal = priceFormatter.format( total ); 160 161 return formattedTotal; 162 } 163 164 public Document viewCartXML() 165 { 166 XMLCreator xmlCreator = new XMLCreator(); 167 Node cartNode = xmlCreator.initialize( "cart" ); 168 169 xmlCreator.addAttribute( cartNode, "numItems", 170 String.valueOf( getLength() ) ); 171 xmlCreator.addAttribute( cartNode, "total", getTotal() ); 172 173 if ( getLength() != 0 ) { 174 175 for( int i = 0; i < getLength(); i++ ) { 176 Node itemNode = xmlCreator.addChild( cartNode, 177 "item" ); 178 Fig. 16.17 Code listing for Shopping-Cart.java (Part 6).Lines 150-162Line 164Lines 164-200
179 xmlCreator.addTextNode( xmlCreator.addChild( 180 itemNode, "productID" ), getProductID( i ) ); 181 xmlCreator.addTextNode( xmlCreator.addChild( 182 itemNode, "quantity" ), 183 String.valueOf( getQuantity( i ) ) ); 184 xmlCreator.addTextNode( xmlCreator.addChild( 185 itemNode, "price" ), getFormattedPrice( i ) ); 186 187 String description[] = getDescription( i ); 188 189 xmlCreator.addTextNode( xmlCreator.addChild( 190 itemNode, "title" ), description[ 0 ] ); 191 xmlCreator.addTextNode( xmlCreator.addChild( 192 itemNode, "author" ), description[ 1 ] ); 193 xmlCreator.addTextNode( xmlCreator.addChild( 194 itemNode, "isbn" ), description[ 2 ] ); 195 } 196 197 } 198 199 return xmlCreator.getDocument(); 200 } 201 } Fig. 16.17 Code listing for Shopping-Cart.java (Part 7).