Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Mastering Enterprise JavaBeans™ and the Java 2 Platform, Enterprise Edition - Roman E

..pdf
Скачиваний:
41
Добавлен:
24.05.2014
Размер:
6.28 Mб
Скачать

J2EE in the Real World: Combining Servlets with Enterprise JavaBeans 481

break;

}

/*

*If the parameter represents a quantity

*of a particular product the user is interested

*in, then we should update that product's

*quantity to reflect this new value.

*/

 

else {

 

/*

 

* Convert the

quantity to int format

*/

 

int quantity =

0;

try {

 

quantity =

Integer.parseInt(paramValue);

}

catch (NumberFormatException e) {

throw new ServletException("Bad parameter to servlet: " + paramName + ", " + paramValue);

}

/*

*Use the ProductBase servlet to convert the

*product ID into a Product.

*/

Product product = null; try {

product = productBase.getProduct(paramName);

}

catch (Exception e) {

throw new ServletException(e.toString());

}

/*

* Set the new quantity. */

try {

quote.setProductQuantity(product, quantity);

}

catch (Exception e) {

throw new ServletException(e.toString());

}

}

}

/*

* Recalculate all totals based upon new quantities

Source 15.6 ShowQuoteServlet.java (continues).

Go back to the first page for a quick link to buy this book online!

482 M A S T E R I N G E N T E R P R I S E J A V A B E A N S

*/ try {

pricer.price(quote);

}

catch (Exception e) { log(e);

throw new ServletException(e.toString());

}

/*

* Otherwise, show the current quote again */

int num = quote.getNumberOfItems(); if (num > 0) {

out.println(

"<form action=\"" + response.encodeUrl("/servlet/showquote") + "\" method=\"get\">" +

"<table>" + "<tr>" +

"<th align=left> Name </TH>" + "<th align=left> Quantity </TH>" +

"<th align=left> Individual Base Price </TH>" + "<th align=left> Individual Discount </TH>" +

"<th align=left><strong> Total Price </strong></TH>" + "<th align=left>Modify Quantity</TH>" +

"</tr>");

/*

* Print each line item in the quote */

Vector lineItems = quote.getLineItems(); for (int i=0; i < lineItems.size(); i++) {

QuoteLineItem li

= (QuoteLineItem) lineItems.elementAt(i);

int quantity

= li.getQuantity();

double discount

= li.getDiscount();

Product product

= li.getProduct();

String productID

=

((ProductPK)product.getPrimaryKey()).productID;

double basePrice

= product.getBasePrice();

out.println( "<tr>" +

"<td bgcolor=\"#ffffaa\">" + "<strong><a href=\"" +

Source 15.6 ShowQuoteServlet.java (continues).

Go back to the first page for a quick link to buy this book online!

J2EE in the Real World: Combining Servlets with Enterprise JavaBeans 483

response.encodeUrl( "/servlet/productdetails?productID=" + productID) +

"\">" + product.getName() + "</a></strong>" + "</td>" +

"<td align=\"right\" bgcolor=\"#ffffff\">" + li.getQuantity() +

"</td>" +

"<td bgcolor=\"#ffffaa\" align=\"right\">" + format(basePrice) +

"</td>" +

"<td bgcolor=\"#ffffaa\" align=\"right\">" + format(discount) +

"</td>" +

"<td bgcolor=\"#ffffaa\" align=\"right\">" + format((basePrice - discount) * quantity) + "</td>" +

"<td><input type=\"text\" name=\"" + productID + "\" value=\"" + quantity + "\">" +

"</td>" +

"</td></tr>");

}

/*

* Print the total at the bottom of the table */

out.println(

"<tr><td colspan=\"5\" bgcolor=\"#ffffff\">" + "<br></td></tr>" +

"<tr>" +

"<td colspan=\"2\" align=\"right\"" + "bgcolor=\"#ffffff\">" + "Subtotal:</td>" +

"<td bgcolor=\"#ffffaa\" align=\"right\">" + format(quote.getSubtotal()) + "</td>" + "</td><td><br></td></tr>" +

"<tr>" +

"<td colspan=\"2\" align=\"right\"" + "bgcolor=\"#ffffff\">" +

"Sales Tax:</td>" +

Source 15.6 ShowQuoteServlet.java (continues).

Go back to the first page for a quick link to buy this book online!

484 M A S T E R I N G E N T E R P R I S E J A V A B E A N S

"<td bgcolor=\"#ffffaa\" align=\"right\">" + format(quote.getTaxes()) + "</td>" + "</td><td><br></td></tr>" +

"<tr>" +

"<td colspan=\"2\" align=\"right\"" + "bgcolor=\"ffffff\">" +

"<font color=\"ff0000\">" +

"<strong>Grand Total:</strong></font></td>" + "<td bgcolor=\"ffffaa\" align=\"right\">" + format(quote.getTotalPrice()) + "</td>" + "</td><td><br></td></tr>" +

"</table>");

/*

*Print out links and buttons for user feedback.

*When the user clicks a button to perform an

*action (such as submitting an order), this

*servlet will be called again with a parameter

*instructing the servlet about what to do. We

*processed those parameters at the beginning of

*this method.

*/

out.println("<p>   <p><a href=\"" + response.encodeUrl("/servlet/catalog") + "\">See the Catalog</a>      " +

"<input type=\"reset\"" +

"value=\"Reset Values\">      " +

"<input type=\"submit\" name=\"Update\"" + "value=\"Update Quantities\">      " +

"<input type=\"submit\" name=\"Order\"" + "value=\"Submit Order\">      " +

"<input type=\"submit\" name=\"Clear\"" + "value=\"Clear Quote\">      ");

}

/*

*If there are no products, print out that the

*quote is empty.

*/ else {

out.println(

"<font size=\"+2\">" +

Source 15.6 ShowQuoteServlet.java (continues).

Go back to the first page for a quick link to buy this book online!

J2EE in the Real World: Combining Servlets with Enterprise JavaBeans 485

"Your quote is empty.</font>" + "<br>   <br>" + "<center><a href=\"" +

response.encodeUrl("/servlet/catalog") + "\">Back to the Catalog</a> </center>");

}

out.println("</body> </html>"); out.close();

}

/**

* Currency localization formatting */

private String format(double d) {

NumberFormat nf = NumberFormat.getCurrencyInstance(); return nf.format(d);

}

private void log(Exception e) { getServletConfig().getServletContext().log(e, "");

}

public String getServletInfo() {

return "The ShowQuote servlet returns information about" +

"the products that the user is in the process of ordering.";

}

}

Source 15.6 ShowQuoteServlet.java (continued).

Next, our doGet() method is responsible for showing the quote to the user and handling any requests for modifications to the quote. The simplest case is when the user first connects to this servlet—we just print out the user’s current Quote, by retrieving each Quote Line Item from the Quote and displaying it to the end user. This is shown in Figure 15.5.

The user can update the quantities of his or her quote by changing the text box values, then pressing the Update button. When this happens, extra HTTP parameters are passed back to the servlet. The name of each HTTP parameter is a Product ID, and the value of each HTTP parameter is the new desired quantity. When the servlet is called with these parameters, our servlet parses each parameter and in turn updates the quantities on the quote. It then tells our Pricer EJB object to price the entire quote, yielding the new values (with possibly new discounts). We then redisplay the Quote to the user.

Go back to the first page for a quick link to buy this book online!

486 M A S T E R I N G E N T E R P R I S E J A V A B E A N S

Figure 15.5 Viewing the initial quote.

The user can also clear the quote by pressing the Clear button. When this happens, an HTTP parameter is passed back to our servlet called “Clear.” If we see the “Clear” parameter, we call the Quote’s clear() method, which empties all the Quote Line Items. Note that the user can still shop around because the Quote is still in the servlet session and the Quote is still associated with that Customer. Clearing the quote is shown in Figure 15.6.

The Purchasing Servlet

Finally, when the user is happy, he or she can turn the shopping cart into a permanent order and get charged for the order by clicking the Submit button. When this happens we need to convert the Quote stateful session bean into an Order entity bean. Fortunately, we designed the Quote bean to be smart enough to convert itself into an order automatically. Our servlet needs to contact a Bank Teller to bill the customer. Once the transaction is complete, we display the user’s Order number (you can extend this example to allow users to query the status of orders by submitting their Order number).

The code for PurchaseServlet.java is shown in Source 15.7.

Go back to the first page for a quick link to buy this book online!

J2EE in the Real World: Combining Servlets with Enterprise JavaBeans 487

Figure 15.6 Clearing the quote.

package com.wiley.compBooks.ecommerce;

import java.io.*; import java.util.*; import java.text.*; import javax.servlet.*;

import javax.servlet.http.*; import javax.naming.*;

/**

*This servlet performs an actual purchase of goods, printing

*out a receipt.

*

*By the time this servlet is called, the user has logged in (via the

*Login servlet) and has a shopping cart started (i.e., Quote bean).

*Because this servlet is pooled and reused for different user

*requests, the servlet code does not store any information specific

*to any user. Rather, we store a reference to the user's Quote in

*the user's HttpSession object, which is globally accessible to all

Source 15.7 PurchaseServlet.java (continues).

Go back to the first page for a quick link to buy this book online!

488 M A S T E R I N G E N T E R P R I S E J A V A B E A N S

* servlets. */

public class PurchaseServlet extends HttpServlet {

// Bank Teller EJB Object for performing bank transactions private Teller teller;

/*

*Our purchase servlet needs to conduct a transaction. When

*a purchase is made, an order needs to be submitted and

*the customer needs to be billed. If either of these

*operations fails, both should fail. Therefore, we run both

*operations together under a flat transaction. For a servlet

*to begin and end a transaction, it must use the Java

*Transaction API (JTA), as described in Chapter 10. The JTA

*UserTransaction interface is used for exactly this purpose.

*The EJB server must make this interface available to us

*via JNDI. We'll look it up using JNDI in the init() method.

*/

private javax.transaction.UserTransaction userTran;

/**

*The servlet engine calls this method once to initialize a

*servlet instance.

*

*In the body of this method, we need to acquire a Pricer

*EJB Object for pricing the quotes, as well as the JTA

*UserTransaction interface, used for demarcating

*transactional boundaries.

*/

public void init(ServletConfig config) throws ServletException {

super.init(config);

try { /*

*Get the JNDI initialization parameters. We

*externalize these settings to the servlet properties

*file to allow end users to dynamically reconfigure

*their environment without recompilation.

*/

String initCtxFactory = getInitParameter(Context.INITIAL_CONTEXT_FACTORY);

String providerURL = getInitParameter(Context.PROVIDER_URL);

/*

* Add the JNDI init parameters to a properties object */

Source 15.7 PurchaseServlet.java (continues).

Go back to the first page for a quick link to buy this book online!

J2EE in the Real World: Combining Servlets with Enterprise JavaBeans 489

Properties env = new Properties(); env.put(Context.INITIAL_CONTEXT_FACTORY, initCtxFactory); env.put(Context.PROVIDER_URL, providerURL);

/*

* Get the initial context using the above startup params */

Context ctx = new InitialContext(env);

/*

* Look up the Home Object */

TellerHome tellerHome = (TellerHome) ctx.lookup("Ecommerce.TellerHome");

/*

* Create a Pricer EJB Object */

teller = tellerHome.create();

/*

* Look up the JTA UserTransaction interface via JNDI */

userTran = (javax.transaction.UserTransaction) ctx.lookup("javax.transaction.UserTransaction");

}

catch (Exception e) { log(e);

throw new ServletException(e.toString());

}

}

/**

*The servlet engine calls this method when the user's

*desktop browser sends an HTTP GET request.

*/

public void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

/*

*Get the user's HttpSession and from that get the user's

*current quote.

*/

HttpSession session = request.getSession(false); if (session == null) {

/*

* Redirect user to login page if no session */

Source 15.7 PurchaseServlet.java (continues).

Go back to the first page for a quick link to buy this book online!

490 M A S T E R I N G E N T E R P R I S E J A V A B E A N S

response.sendRedirect(response.encodeUrl("/servlet/login"));

return;

}

Object obj = session.getValue("quote"); if (obj == null) {

/*

* Redirect user to login page if no session */

response.sendRedirect(response.encodeUrl("/servlet/login"));

return;

}

Quote quote = (Quote) obj;

/*

*Now, we write the response. Set content-type

*header, indicating that we will be writing in

*HTML.

*/

response.setContentType("text/html"); PrintWriter out = response.getWriter();

/*

* Then write the data of the response. Start with the header. */

out.println( "<html>" +

"<head><title> Thank you </title></head>" +

"<body bgcolor=\"#ffffff\">" + "<center>" +

"<hr> <br>  " + "<h1>" +

"<font size=\"+3\" color=\"red\">Jasmine's </font>" + "<font size=\"+3\" color=\"purple\">Computer </font>" + "<font size=\"+3\" color=\"green\">Parts</font>" + "</h1>" +

"</center>" +

"<br>   <hr> <br>  ");

Order order = null; try {

/*

*Begin a new user transaction. We require a

*transaction here so that we can charge the

*user and generate the order atomically.

*/

userTran.begin();

Source 15.7 PurchaseServlet.java (continues).

Go back to the first page for a quick link to buy this book online!