Tải bản đầy đủ (.pdf) (187 trang)

Advanced Java 2 Platform HOW TO PROGRAM phần 7 pps

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (1.95 MB, 187 trang )

1060 Enterprise Java Case Study: Presentation and Controller Logic Chapter 18
LoginServlet uses the Customer EJB to validate the userID and password that
the customer entered. Lines 39–44 obtain a reference to the CustomerHome interface.
Lines 47–48 invoke CustomerHome method findByLogin, which returns a remote
reference to the Customer with the userID and password that the user provided.
Once the Customer is found, lines 59–69 build a simple XML document that indicates
the customer has successfully logged into the store.
Lines 74–82 catch a NamingException if the Customer EJB cannot be found in
the JNDI directory. If no Customer is found that matches the userID and password the
user entered, lines 85–93 catch a FinderException. Each catch block builds an
XML error message for the client to display. Lines 96–98 present the content to the client.
18.5.3 ViewOrderHistoryServlet
Registered customers may want to see information about orders they have placed in the
past. ViewOrderHistoryServlet (Fig. 18.19) allows customers to see orders they
have placed, along with the dates the orders were taken, the total costs of the orders and
whether or not the orders were shipped from the warehouse.
Fig. 18.18
Fig. 18.18Fig. 18.18
Fig. 18.18 LoginServlet for authenticating registered Customers (part 4 of
4).(Images courtesy Pixo, Inc. or © 2001 Nokia Mobile Phones.)
Chapter 18 Enterprise Java Case Study: Presentation and Controller Logic 1061
1 // ViewOrderHistoryServlet.java
2 // ViewOrderHistoryServlet presents a list of previous Orders
3 // to the Customer.
4 package com.deitel.advjhtp1.bookstore.servlets;
5
6 // Java core packages
7 import java.io.*;
8 import java.util.*;
9
10 // Java extension packages


11 import javax.servlet.*;
12 import javax.servlet.http.*;
13 import javax.naming.*;
14 import javax.rmi.*;
15 import javax.ejb.*;
16
17 // third-party packages
18 import org.w3c.dom.*;
19
20 // Deitel packages
21 import com.deitel.advjhtp1.bookstore.model.*;
22 import com.deitel.advjhtp1.bookstore.ejb.*;
23 import com.deitel.advjhtp1.bookstore.exceptions.*;
24
25 public class ViewOrderHistoryServlet extends XMLServlet {
26
27 // respond to HTTP get requests
28 public void doGet( HttpServletRequest request,
29 HttpServletResponse response )
30 throws ServletException, IOException
31 {
32 Document document = getDocumentBuilder().newDocument();
33
34 HttpSession session = request.getSession();
35 String userID = ( String )
36 session.getAttribute( "userID" );
37
38 // build order history using Customer EJB
39 try {
40 InitialContext context = new InitialContext();

41
42 // look up Customer EJB
43 Object object =
44 context.lookup( "java:comp/env/ejb/Customer" );
45
46 CustomerHome customerHome = ( CustomerHome )
47 PortableRemoteObject.narrow(
48 object, CustomerHome.class );
49
50 // find Customer with given userID
51 Customer customer =
Fig. 18.19
Fig. 18.19Fig. 18.19
Fig. 18.19
ViewOrderHistoryServlet for viewing customer’s previously
placed
Orders (part 1 of 4). (Images courtesy Pixo, Inc. or © 2001 Nokia
Mobile Phones.)
1062 Enterprise Java Case Study: Presentation and Controller Logic Chapter 18
52 customerHome.findByUserID( userID );
53
54 // create orderHistory element
55 Element rootNode = ( Element ) document.appendChild(
56 document.createElement( "orderHistory" ) );
57
58 // get Customer's Order history
59 Iterator orderHistory =
60 customer.getOrderHistory().iterator();
61
62 // loop through Order history and add XML elements

63 // to XML document for each Order
64 while ( orderHistory.hasNext() ) {
65 OrderModel orderModel =
66 ( OrderModel ) orderHistory.next();
67
68 rootNode.appendChild(
69 orderModel.getXML( document ) );
70 }
71 } // end try
72
73 // handle exception when Customer has no Order history
74 catch ( NoOrderHistoryException historyException ) {
75 historyException.printStackTrace();
76
77 document.appendChild( buildErrorMessage( document,
78 historyException.getMessage() ) );
79 }
80
81 // handle exception when looking up Customer EJB
82 catch ( NamingException namingException ) {
83 namingException.printStackTrace();
84
85 String error = "The Customer EJB was not found in " +
86 "the JNDI directory.";
87
88 document.appendChild( buildErrorMessage(
89 document, error ) );
90 }
91
92 // handle exception when Customer is not found

93 catch ( FinderException finderException ) {
94 finderException.printStackTrace();
95
96 String error = "The Customer with userID " + userID +
97 " was not found.";
98
99 document.appendChild( buildErrorMessage(
100 document, error ) );
101 }
102
Fig. 18.19
Fig. 18.19Fig. 18.19
Fig. 18.19
ViewOrderHistoryServlet for viewing customer’s previously
placed
Orders (part 2 of 4). (Images courtesy Pixo, Inc. or © 2001 Nokia
Mobile Phones.)
Chapter 18 Enterprise Java Case Study: Presentation and Controller Logic 1063
103 // ensure content is written to client
104 finally {
105 writeXML( request, response, document );
106 }
107
108 } // end method doGet
109 }
Fig. 18.19
Fig. 18.19Fig. 18.19
Fig. 18.19 ViewOrderHistoryServlet for viewing customer’s previously
placed
Orders (part 3 of 4). (Images courtesy Pixo, Inc. or © 2001 Nokia

Mobile Phones.)
1064 Enterprise Java Case Study: Presentation and Controller Logic Chapter 18
Customer EJB method getOrderHistory returns a Collection of the cus-
tomer’s previous orders. Lines 51–52 obtain the Customer EJB for the Customer, who
must be logged into the bookstore. Lines 59–60 retrieve an Iterator for the customer’s
order history. Lines 64–70 loop through the order history and build the XML document to
present to the client.
If the customer has not placed any orders in our on-line store, method getOrder-
History throws a NoOrderHistoryException. Lines 74–79 catch this exception
and build an error message to display to the customer. If the CustomerHome interface
could not be found or the Customer could not be found in the database, a NamingEx-
ception or FinderException is thrown, respectively. Lines 82–101 catch each of
these exceptions and construct an error message, using method buildErrorMessage.
Line 105 presents the content to the client, using method writeXML.
18.5.4 ViewOrderServlet
ViewOrderServlet (Fig. 18.20) displays the details of an order. CheckoutServ-
let forwards clients to ViewOrderServlet when a customer places an order.
ViewOrderHistoryServlet forwards clients to ViewOrderServlet to present
the details of an order that has already been placed.
Fig. 18.19
Fig. 18.19Fig. 18.19
Fig. 18.19 ViewOrderHistoryServlet for viewing customer’s previously
placed
Orders (part 4 of 4). (Images courtesy Pixo, Inc. or © 2001 Nokia
Mobile Phones.)
Chapter 18 Enterprise Java Case Study: Presentation and Controller Logic 1065
Lines 39–44 obtain a reference to interface OrderHome. Lines 47–48 retrieve the
orderID parameter from the request object. Line 51 invokes OrderHome method
findByPrimaryKey to obtain a remote reference to the Order with the given
orderID. Lines 54–58 get the OrderModel for the Order and append its XML repre-

sentation to the XML document.
Lines 63–71 catch a NamingException, which is thrown from method lookup
if the Order EJB cannot be found in the JNDI directory. Lines 74–82 catch a Finder-
Exception, which is thrown by method findByPrimaryKey if an Order with the
given orderID is not found. Line 86 presents the XML document to the client, using
method writeXML.
1 // ViewOrderServlet.java
2 // ViewOrderServlet presents the contents of a Customer's
3 // Order.
4 package com.deitel.advjhtp1.bookstore.servlets;
5
6 // Java core packages
7 import java.io.*;
8
9 // Java extension packages
10 import javax.servlet.*;
11 import javax.servlet.http.*;
12 import javax.naming.*;
13 import javax.ejb.*;
14 import javax.rmi.*;
15
16 // third-party packages
17 import org.w3c.dom.*;
18
19 // Deitel packages
20 import com.deitel.advjhtp1.bookstore.model.*;
21 import com.deitel.advjhtp1.bookstore.ejb.*;
22
23 public class ViewOrderServlet extends XMLServlet {
24

25 // respond to HTTP get requests
26 public void doGet( HttpServletRequest request,
27 HttpServletResponse response )
28 throws ServletException, IOException
29 {
30 Document document = getDocumentBuilder().newDocument();
31 Integer orderID = null;
32
33 // look up Order EJB and get details of Order with
34 // given orderID
35 try {
36 InitialContext context = new InitialContext();
37
38 // look up Order EJB
Fig. 18.20
Fig. 18.20Fig. 18.20
Fig. 18.20
ViewOrderServlet for viewing details of an order (part 1 of 3). (Images
courtesy Pixo, Inc. or © 2001 Nokia Mobile Phones.)
1066 Enterprise Java Case Study: Presentation and Controller Logic Chapter 18
39 Object object =
40 context.lookup( "java:comp/env/ejb/Order" );
41
42 OrderHome orderHome = ( OrderHome )
43 PortableRemoteObject.narrow(
44 object, OrderHome.class );
45
46 // get orderID from request object
47 orderID = new Integer(
48 request.getParameter( "orderID" ) );

49
50 // find Order with given orderID
51 Order order = orderHome.findByPrimaryKey( orderID );
52
53 // get Order details as an OrderModel
54 OrderModel orderModel = order.getOrderModel();
55
56 // add Order details to XML document
57 document.appendChild(
58 orderModel.getXML( document ) );
59
60 } // end try
61
62 // handle exception when looking up Order EJB
63 catch ( NamingException namingException ) {
64 namingException.printStackTrace();
65
66 String error = "The Order EJB was not found in " +
67 "the JNDI directory.";
68
69 document.appendChild( buildErrorMessage(
70 document, error ) );
71 }
72
73 // handle exception when Order is not found
74 catch ( FinderException finderException ) {
75 finderException.printStackTrace();
76
77 String error = "An Order with orderID " + orderID +
78 " was not found.";

79
80 document.appendChild( buildErrorMessage(
81 document, error ) );
82 }
83
84 // ensure content is written to client
85 finally {
86 writeXML( request, response, document );
87 }
88
89 } // end method doGet
90 }
Fig. 18.20
Fig. 18.20Fig. 18.20
Fig. 18.20
ViewOrderServlet for viewing details of an order (part 2 of 3). (Images
courtesy Pixo, Inc. or © 2001 Nokia Mobile Phones.)
Chapter 18 Enterprise Java Case Study: Presentation and Controller Logic 1067
18.5.5 GetPasswordHintServlet
Registered Customers occasionally forget their passwords. GetPasswordHint-
Servlet (Fig. 18.21) provides hints to help Customers remember their passwords. The
customer supplies the password hint as part of the registration process.
Fig. 18.20
Fig. 18.20Fig. 18.20
Fig. 18.20 ViewOrderServlet for viewing details of an order (part 3 of 3). (Images
courtesy Pixo, Inc. or © 2001 Nokia Mobile Phones.)
1068 Enterprise Java Case Study: Presentation and Controller Logic Chapter 18
The hint is stored with other customer registration information in the Customer EJB.
Lines 38–47 look up the CustomerHome interface and retrieve the Customer EJB
remote reference. Customer EJB method getPasswordHint (line 55) returns the hint

the user entered when registering on the site. Line 58 adds the hint to the XML document.
In this chapter, we presented the controller and presentation logic for the Deitel Book-
store. This controller logic provides an HTTP interface to the business logic objects we
present in Chapters 18 and 19. Java servlets provide a robust and flexible controller logic
implementation. XSLT presentation logic allows the Deitel Bookstore application to sup-
port many different client types without a need for changes in controller logic implementa-
tions. In Chapters 19 and 20, we present the business logic for the Deitel Bookstore, using
Enterprise JavaBeans.
1 // GetPasswordHintServlet.java
2 // GetPasswordHintServlet allows a customer to retrieve a
3 // lost password.
4 package com.deitel.advjhtp1.bookstore.servlets;
5
6 // Java core packages
7 import java.io.*;
8
9 // Java extension packages
10 import javax.servlet.*;
11 import javax.servlet.http.*;
12 import javax.naming.*;
13 import javax.ejb.*;
14 import javax.rmi.*;
15
16 // third-party packages
17 import org.w3c.dom.*;
18
19 // Deitel packages
20 import com.deitel.advjhtp1.bookstore.model.*;
21 import com.deitel.advjhtp1.bookstore.ejb.*;
22

23 public class GetPasswordHintServlet extends XMLServlet {
24
25 // respond to HTTP get requests
26 public void doGet( HttpServletRequest request,
27 HttpServletResponse response )
28 throws ServletException, IOException
29 {
30 Document document = getDocumentBuilder().newDocument();
31 String userID = request.getParameter( "userID" );
32
33 // get password hint from Customer EJB
34 try {
35 InitialContext context = new InitialContext();
36
37 // look up Customer EJB
38 Object object =
Fig. 18.21
Fig. 18.21Fig. 18.21
Fig. 18.21
GetPasswordHintServlet for viewing a Customer’s password hint
(part 1 of 3). (Images courtesy Pixo, Inc. or © 2001 Nokia Mobile Phones.)
Chapter 18 Enterprise Java Case Study: Presentation and Controller Logic 1069
39 context.lookup( "java:comp/env/ejb/Customer" );
40
41 CustomerHome customerHome = ( CustomerHome )
42 PortableRemoteObject.narrow( object,
43 CustomerHome.class );
44
45 // find Customer with given userID
46 Customer customer =

47 customerHome.findByUserID( userID );
48
49 // create passwordHint element in XML document
50 Element hintElement =
51 document.createElement( "passwordHint" );
52
53 // add text of passwordHint to XML element
54 hintElement.appendChild( document.createTextNode(
55 customer.getPasswordHint() ) );
56
57 // append passwordHint element to XML document
58 document.appendChild( hintElement );
59
60 } // end try
61
62 // handle exception when looking up Customer EJB
63 catch ( NamingException namingException ) {
64 namingException.printStackTrace();
65
66 String error = "The Customer EJB was not found in " +
67 "the JNDI directory.";
68
69 document.appendChild( buildErrorMessage(
70 document, error ) );
71 }
72
73 // handle exception when Customer is not found
74 catch ( FinderException finderException ) {
75 finderException.printStackTrace();
76

77 String error = "No customer was found with userID " +
78 userID + ".";
79
80 document.appendChild( buildErrorMessage(
81 document, error ) );
82 }
83
84 // ensure content is written to client
85 finally {
86 writeXML( request, response, document );
87 }
88
89 } // end method doGet
90 }
Fig. 18.21
Fig. 18.21Fig. 18.21
Fig. 18.21
GetPasswordHintServlet for viewing a Customer’s password hint
(part 2 of 3). (Images courtesy Pixo, Inc. or © 2001 Nokia Mobile Phones.)
1070 Enterprise Java Case Study: Presentation and Controller Logic Chapter 18
SELF-REVIEW EXERCISES
18.1 Which part of the MVC architecture do the servlets in the Deitel Bookstore implement? Which
part of the MVC architecture do the XSL transformations implement?
Fig. 18.21
Fig. 18.21Fig. 18.21
Fig. 18.21 GetPasswordHintServlet for viewing a Customer’s password hint
(part 3 of 3). (Images courtesy Pixo, Inc. or © 2001 Nokia Mobile Phones.)
Chapter 18 Enterprise Java Case Study: Presentation and Controller Logic 1071
18.2 Write a code snippet for looking up the ShoppingCart EJB in the JNDI directory and cre-
ating a new instance using interface ShoppingCartHome. Be sure to catch any exceptions thrown

when looking up the EJB or creating a new instance.
18.3 How does ViewOrderServlet (Fig. 18.20) locate the Order that the user requested to
view?
18.4 What common functionality does class XMLServlet (Fig. 18.1) provide for the servlets in
the Deitel Bookstore? Describe the purposes of the main methods of class XMLServlet.
18.5 How does class XMLServlet determine the name of the XSLT stylesheet to use when
transforming content generated by the servlet? What benefit does this strategy provide?
18.6 How does class XMLServlet determine the particular XSLT stylesheet to use when trans-
forming content generated by the servlet for a particular type of client? What benefit does this strategy
provide?
ANSWERS TO SELF-REVIEW EXERCISES
18.1 The servlets implement the controller in the MVC architecture, because they handle all user re-
quests and process user input. The XSL transformations implement the view in the MVC design pat-
tern because they produce presentations of application data.
18.2 The following code snippet looks up the ShoppingCart EJB in the JNDI directory and
creates a new instance using interface ShoppingCartHome:
try {
InitialContext context = new InitialContext;
Object object = context.lookup(
"java:comp/env/ejb/ShoppingCart" );
ShoppingCartHome shoppingCartHome =
( ShoppingCartHome ) PortableRemoteObject.narrow(
object, ShoppingCartHome.class );
ShoppingCart shoppingCart = shoppingCartHome.create();
}
catch ( NamingException namingException ) {
namingException.printStackTrace();
}
catch ( CreateException createException ) {
createException.printStackTrace();

}
18.3 ViewOrderServlet uses OrderHome method findByPrimaryKey to locate the
Order, with the orderID passed as a parameter to the HttpServletRequest object.
18.4 Class XMLServlet provides a common init method for initializing the Document-
BuilderFactory, TransformerFactory and properties each servlet uses. Class XMLServ-
let provides method buildErrorMessage, which creates an XML element to describe an error
message. Class XMLServlet also provides method writeXML, which uses method transform
to transform the XML content generated by each servlet using client-specific XSL transformations.
1072 Enterprise Java Case Study: Presentation and Controller Logic Chapter 18
18.5 Class XMLServlet has property XSLFileName that specifies the name of the XSL file to
use when transforming the servlet’s content. Class XMLServlet’s init method sets the XSL-
FileName property to the value specified in the XSL_FILE servlet initialization parameter. Deter-
mining the file name from an initialization parameter enables the deployer to specify the file name
when deploying the application. The file name can be changed later without the need to recompile the
servlet.
18.6 Class XMLServlet uses a ClientModel to determine which directory contains the XSL
transformation for XML content generated by the servlet. Class XMLServlet creates a list of Cli-
entModels from an XML configuration file when the servlet is first initialized. Each ClientMod-
el specifies a User-Agent header that uniquely identifies the client, the Content-Type for
sending data to the client and the directory in which the XSL transformations can be found for gen-
erating content specific to the client. This enables the developer to add support for new client types
without modifying any servlet code. The developer simply provides a set of XSL transformations for
the new client type and includes information about the new client type in clients.xml.
19
Enterprise Java Case
Study: Business Logic
Part 1
Objectives
• To understand the EJB data model for the Deitel
Bookstore case study.

• To understand the business logic used in the Deitel
Bookstore case study.
• To understand performance issues involved in
transmitting objects over RMI-IIOP.
• To understand the benefits of EJBs that use container-
managed persistence for database storage.
• To understand the usage of primary-key classes that
represent complex primary keys.
Drive thy business, or it will drive thee.
Benjamin Franklin
Everybody’s business is nobody’s business, and nobody’s
business is my business.
Clara Barton
1074 Enterprise Java Case Study: Business Logic Part 1 Chapter 19
19.1 Introduction
In this chapter, we present the EJB business logic for the shopping-cart e-commerce model,
and entity EJBs that provide an object-based interface to the store’s product catalog. After
reading this chapter, you will understand the use of EJBs in an e-commerce application
context, as well as more advanced EJB topics, such as custom primary-key classes and
many-to-many relationships.
19.2 EJB Architecture
EJBs implement the business logic of the Deitel Bookstore case study. Servlet controller
logic communicates with EJB business logic to process user requests and retrieve data from
the database. For example, GetProductServlet handles Customer requests to view
Product details. GetProductServlet uses the JNDI directory to locate the Prod-
uct EJB’s home interface. GetProductServlet invokes ProductHome method
findByPrimaryKey to retrieve a remote reference to the Product with the requested
Outline
19.1 Introduction
19.2 EJB Architecture

19.3 ShoppingCart Implementation
19.3.1 ShoppingCart Remote Interface
19.3.2 ShoppingCartEJB Implementation
19.3.3 ShoppingCartHome Interface
19.4 Product Implementation
19.4.1 Product Remote Interface
19.4.2 ProductEJB Implementation
19.4.3 ProductHome Interface
19.4.4 ProductModel
19.5 Order Implementation
19.5.1 Order Remote Interface
19.5.2 OrderEJB Implementation
19.5.3 OrderHome Interface
19.5.4 OrderModel
19.6 OrderProduct Implementation
19.6.1 OrderProduct Remote Interface
19.6.2 OrderProductEJB Implementation
19.6.3 OrderProductHome Interface
19.6.4 OrderProductPK Primary-Key Class
19.6.5 OrderProductModel
Chapter 19 Enterprise Java Case Study: Business Logic Part 1 1075
ISBN. GetProductServlet must then use methods in the Product remote interface
to retrieve information about the Product. Each method call on the Product remote in-
terface incurs network traffic, because communication with the EJB is performed over
RMI-IIOP (discussed in Chapter 27). If separate method calls were required to retrieve the
Product’s title, author, price and other properties, the network overhead would
severely limit the performance and scalability of the application.
The entity EJBs in the Deitel Bookstore case study alleviate this network congestion
by using models to transmit EJB data. A model is a Serializable class that contains
all the data for a given EJB. These classes are called models because each model class

implements a piece of the model in the MVC architecture. Each entity EJB provides a get
method that returns its model representation. For example, the Product EJB has method
getProductModel, which returns a ProductModel containing the ISBN, author,
price and other properties of a Product. Many of the entity EJBs also provide create
methods that accept models as arguments. These create methods create new EJB instances
and set the data in the EJB, using property values provided in the model.
Performance Tip 19.1
Aggregating entity EJB data into a model class and returning instances of this model class
from EJB business methods can improve EJB performance by reducing the network traffic
associated with multiple method calls over RMI-IIOP.
19.1
Figure 19.1 shows a sample communication between servlet GetProductServlet
and the Product EJB. To get the details of a given Product, GetProductServlet
invokes Product method getProductModel. Method getProductModel returns
a ProductModel object containing data for a given Product and serializes the Pro-
ductModel over RMI-IIOP. GetProductServlet retrieves the ProductModel’s
property values to build the output for the user.
19.3 ShoppingCart Implementation
Stateful session EJB ShoppingCart implements business logic for managing each Cus-
tomer’s shopping cart. The ShoppingCart EJB consists of a remote interface, an EJB
implementation and a home interface. We implement ShoppingCart as a stateful ses-
sion EJB so each ShoppingCart instance will persist throughout a customer’s shopping
session. Just as customers of brick-and-mortar stores use shopping carts to gather products,
customers of our on-line store use ShoppingCart EJBs to gather products while they
browse through our store.
19.3.1 ShoppingCart Remote Interface
Remote interface ShoppingCart (Fig. 19.2) defines business logic methods available in
the ShoppingCart EJB. Each remote interface method must declare that it throws
RemoteException. Each method also must declare any application-specific exceptions
that may be thrown from the implementation. Method getContents (line 20) returns an

Collection of Products in the ShoppingCart. Method addProduct (lines 23–
24) takes as a String argument the ISBN of a Product to add to the ShoppingCart.
Method addProduct throws ProductNotFoundException, which is an applica-
tion-specific exception that indicates the Product with the given ISBN is not in the da-
tabase and therefore could not be added to the ShoppingCart.
1076 Enterprise Java Case Study: Business Logic Part 1 Chapter 19
Method removeProduct (lines 27–28) removes the Product with the given
ISBN from the ShoppingCart. If the Product with the given ISBN is not found in the
ShoppingCart, method removeProduct throws a ProductNotFoundExcep-
tion.
Method setProductQuantity (lines 32–34) updates the quantity of the
Product with the given ISBN in the ShoppingCart. For example, if there were one
copy of Advanced Java 2 Platform How to Program in the Customer’s Shopping-
Cart, setProductQuantity could be called with the ISBN of Advanced Java How
to Program and the integer 5 to purchase five copies of the book. If the Product with the
given ISBN is not in the ShoppingCart, method setProductQuantity throws the
application-specific ProductNotFoundException.
Method checkout (lines 37–38) places an Order for the Products in the Cus-
tomer’s ShoppingCart. Method checkout takes as a String argument the
userID of the customer placing the Order. Only registered customers may place
Orders. Method getTotal (line 41) returns the total cost of the Products in the Cus-
tomer’s ShoppingCart.
Fig. 19.1
Fig. 19.1Fig. 19.1
Fig. 19.1 Communication between GetProductServlet and Product
EJB.
1 // ShoppingCart.java
2 // ShoppingCart is the remote interface for stateful session
3 // EJB ShoppingCart.
4 package com.deitel.advjhtp1.bookstore.ejb;

5
6 // Java core packages
7 import java.rmi.RemoteException;
8 import java.util.ArrayList;
9
10 // Java extension packages
11 import javax.ejb.EJBObject;
12
13 // Deitel packages
14 import com.deitel.advjhtp1.bookstore.model.*;
15 import com.deitel.advjhtp1.bookstore.exceptions.*;
Fig. 19.2
Fig. 19.2Fig. 19.2
Fig. 19.2
ShoppingCart remote interface for adding, removing and updating
Products, checking out and calculating the Order’s total cost
(part 1 of 2).
ProductModel
GetProductServlet
getProductModel
Servlet Container EJB Container
Product EJB
Chapter 19 Enterprise Java Case Study: Business Logic Part 1 1077
19.3.2 ShoppingCartEJB Implementation
ShoppingCart remote interface implementation ShoppingCartEJB (Fig. 19.3) con-
tains an Collection of OrderProductModels (line 24). An OrderProductMod-
el (Fig. 19.25) represents an item in the ShoppingCart. Each
OrderProductModel contains a Product and that Product’s quantity in the
ShoppingCart. Method ejbCreate (lines 27–30) initializes the Collection (line
29). Method getContents (line 33–36) returns the contents of the ShoppingCart as

a Collection of OrderProductModels.
16
17 public interface ShoppingCart extends EJBObject {
18
19 // get contents of ShoppingCart
20 public Collection getContents() throws RemoteException;
21
22 // add Product with given ISBN to ShoppingCart
23 public void addProduct( String isbn )
24 throws RemoteException, ProductNotFoundException;
25
26 // remove Product with given ISBN from ShoppingCart
27 public void removeProduct( String isbn )
28 throws RemoteException, ProductNotFoundException;
29
30 // change quantity of Product in ShoppingCart with
31 // given ISBN to given quantity
32 public void setProductQuantity( String isbn, int quantity )
33 throws RemoteException, ProductNotFoundException,
34 IllegalArgumentException;
35
36 // checkout ShoppingCart (i.e., create new Order)
37 public Order checkout( String userID )
38 throws RemoteException, ProductNotFoundException;
39
40 // get total cost for Products in ShoppingCart
41 public double getTotal() throws RemoteException;
42 }
1 // ShoppingCartEJB.java
2 // Stateful session EJB ShoppingCart represents a Customer's

3 // shopping cart.
4 package com.deitel.advjhtp1.bookstore.ejb;
5
6 // Java core packages
7 import java.util.*;
8 import java.rmi.RemoteException;
Fig. 19.3
Fig. 19.3Fig. 19.3
Fig. 19.3
ShoppingCartEJB implementation of ShoppingCart remote
interface (part 1 of 7).
Fig. 19.2
Fig. 19.2Fig. 19.2
Fig. 19.2
ShoppingCart remote interface for adding, removing and updating
Products, checking out and calculating the Order’s total cost
(part 2 of 2).
1078 Enterprise Java Case Study: Business Logic Part 1 Chapter 19
9 import java.text.DateFormat;
10
11 // Java extension packages
12 import javax.ejb.*;
13 import javax.naming.*;
14 import javax.rmi.PortableRemoteObject;
15
16 // Deitel packages
17 import com.deitel.advjhtp1.bookstore.model.*;
18 import com.deitel.advjhtp1.bookstore.exceptions.*;
19
20 public class ShoppingCartEJB implements SessionBean {

21 private SessionContext sessionContext;
22
23 // OrderProductModels (Products & quantities) in ShoppingCart
24 private Collection orderProductModels;
25
26 // create new ShoppingCart
27 public void ejbCreate()
28 {
29 orderProductModels = new ArrayList();
30 }
31
32 // get contents of ShoppingCart
33 public Collection getContents()
34 {
35 return orderProductModels;
36 }
37
38 // add Product with given ISBN to ShoppingCart
39 public void addProduct( String isbn )
40 throws ProductNotFoundException, EJBException
41 {
42 // check if Product with given ISBN is already
43 // in ShoppingCart
44 Iterator iterator = orderProductModels.iterator();
45
46 while ( iterator.hasNext() ) {
47 OrderProductModel orderProductModel =
48 ( OrderProductModel ) iterator.next();
49
50 ProductModel productModel =

51 orderProductModel.getProductModel();
52
53 // if Product is in ShoppingCart, increment quantity
54 if ( productModel.getISBN().equals( isbn ) ) {
55
56 orderProductModel.setQuantity(
57 orderProductModel.getQuantity() + 1 );
58
59 return;
60 }
Fig. 19.3
Fig. 19.3Fig. 19.3
Fig. 19.3
ShoppingCartEJB implementation of ShoppingCart remote
interface (part 2 of 7).
Chapter 19 Enterprise Java Case Study: Business Logic Part 1 1079
61
62 } // end while
63
64 // if Product is not in ShoppingCart, find Product with
65 // given ISBN and add OrderProductModel to ShoppingCart
66 try {
67 InitialContext context = new InitialContext();
68
69 Object object = context.lookup(
70 "java:comp/env/ejb/Product" );
71
72 ProductHome productHome = ( ProductHome )
73 PortableRemoteObject.narrow( object,
74 ProductHome.class );

75
76 // find Product with given ISBN
77 Product product = productHome.findByPrimaryKey( isbn );
78
79 // get ProductModel
80 ProductModel productModel = product.getProductModel();
81
82 // create OrderProductModel for ProductModel and set
83 // its quantity
84 OrderProductModel orderProductModel =
85 new OrderProductModel();
86
87 orderProductModel.setProductModel( productModel );
88 orderProductModel.setQuantity( 1 );
89
90 // add OrderProductModel to ShoppingCart
91 orderProductModels.add( orderProductModel );
92
93 } // end try
94
95 // handle exception when finding Product record
96 catch ( FinderException finderException ) {
97 finderException.printStackTrace();
98
99 throw new ProductNotFoundException( "The Product " +
100 "with ISBN " + isbn + " was not found." );
101 }
102
103 // handle exception when invoking Product EJB methods
104 catch ( Exception exception ) {

105 throw new EJBException( exception );
106 }
107
108 } // end method addProduct
109
110 // remove Product with given ISBN from ShoppingCart
111 public void removeProduct( String isbn )
112 throws ProductNotFoundException
Fig. 19.3
Fig. 19.3Fig. 19.3
Fig. 19.3
ShoppingCartEJB implementation of ShoppingCart remote
interface (part 3 of 7).
1080 Enterprise Java Case Study: Business Logic Part 1 Chapter 19
113 {
114 Iterator iterator = orderProductModels.iterator();
115
116 while ( iterator.hasNext() ) {
117
118 // get next OrderProduct in ShoppingCart
119 OrderProductModel orderProductModel =
120 ( OrderProductModel ) iterator.next();
121
122 ProductModel productModel =
123 orderProductModel.getProductModel();
124
125 // remove Product with given ISBN from ShoppingCart
126 if ( productModel.getISBN().equals( isbn ) ) {
127 orderProductModels.remove( orderProductModel );
128

129 return;
130 }
131
132 } // end while
133
134 // throw exception if Product not found in ShoppingCart
135 throw new ProductNotFoundException( "The Product " +
136 "with ISBN " + isbn + " was not found in your " +
137 "ShoppingCart." );
138
139 } // end method removeProduct
140
141 // set quantity of Product in ShoppingCart
142 public void setProductQuantity( String isbn,
143 int productQuantity ) throws ProductNotFoundException
144 {
145 // throw IllegalArgumentException if uantity not valid
146 if ( productQuantity < 0 )
147 throw new IllegalArgumentException(
148 "Quantity cannot be less than zero." );
149
150 // remove Product if productQuantity less than 1
151 if ( productQuantity == 0 ) {
152 removeProduct( isbn );
153 return;
154 }
155
156 Iterator iterator = orderProductModels.iterator();
157
158 while ( iterator.hasNext() ) {

159
160 // get next OrderProduct in ShoppingCart
161 OrderProductModel orderProductModel =
162 ( OrderProductModel ) iterator.next();
163
164 ProductModel productModel =
Fig. 19.3
Fig. 19.3Fig. 19.3
Fig. 19.3
ShoppingCartEJB implementation of ShoppingCart remote
interface (part 4 of 7).
Chapter 19 Enterprise Java Case Study: Business Logic Part 1 1081
165 orderProductModel.getProductModel();
166
167 // set quantity for Product with given ISBN
168 if ( productModel.getISBN().equals( isbn ) ) {
169 orderProductModel.setQuantity( productQuantity );
170 return;
171 }
172
173 } // end while
174
175 // throw exception if Product not found in ShoppingCart
176 throw new ProductNotFoundException( "The Product " +
177 "with ISBN " + isbn + " was not found in your " +
178 "ShoppingCart." );
179
180 } // end method setProductQuantity
181
182 // checkout of store (i.e., create new Order)

183 public Order checkout( String userID )
184 throws ProductNotFoundException, EJBException
185 {
186 // throw exception if ShoppingCart is empty
187 if ( orderProductModels.isEmpty() )
188 throw new ProductNotFoundException( "There were " +
189 "no Products found in your ShoppingCart." );
190
191 // create OrderModel for Order details
192 OrderModel orderModel = new OrderModel();
193
194 // set OrderModel's date to today's Date
195 orderModel.setOrderDate( new Date() );
196
197 // set list of OrderProduct in OrderModel
198 orderModel.setOrderProductModels( orderProductModels );
199
200 // set OrderModel's shipped flag to false
201 orderModel.setShipped( false );
202
203 // use OrderHome interface to create new Order
204 try {
205 InitialContext context = new InitialContext();
206
207 // look up Order EJB
208 Object object = context.lookup(
209 "java:comp/env/ejb/Order" );
210
211 OrderHome orderHome = ( OrderHome )
212 PortableRemoteObject.narrow( object,

213 OrderHome.class );
214
215 // create new Order using OrderModel and
216 // Customer's userID
Fig. 19.3
Fig. 19.3Fig. 19.3
Fig. 19.3
ShoppingCartEJB implementation of ShoppingCart remote
interface (part 5 of 7).
1082 Enterprise Java Case Study: Business Logic Part 1 Chapter 19
217 Order order = orderHome.create( orderModel, userID );
218
219 // empty ShoppingCart for further shopping
220 orderProductModels = new ArrayList();
221
222 // return Order EJB that was created
223 return order;
224
225 } // end try
226
227 // handle exception when looking up Order EJB
228 catch ( Exception exception ) {
229 throw new EJBException( exception );
230 }
231
232 } // end method checkout
233
234 // get total cost for Products in ShoppingCart
235 public double getTotal()
236 {

237 double total = 0.0;
238 Iterator iterator = orderProductModels.iterator();
239
240 // calculate Order's total cost
241 while ( iterator.hasNext() ) {
242
243 // get next OrderProduct in ShoppingCart
244 OrderProductModel orderProductModel =
245 ( OrderProductModel ) iterator.next();
246
247 ProductModel productModel =
248 orderProductModel.getProductModel();
249
250 // add OrderProduct extended price to total
251 total += ( productModel.getPrice() *
252 orderProductModel.getQuantity() );
253 }
254
255 return total;
256
257 } // end method getTotal
258
259 // set SessionContext
260 public void setSessionContext( SessionContext context )
261 {
262 sessionContext = context;
263 }
264
265 // activate ShoppingCart EJB instance
266 public void ejbActivate() {}

267
Fig. 19.3
Fig. 19.3Fig. 19.3
Fig. 19.3
ShoppingCartEJB implementation of ShoppingCart remote
interface (part 6 of 7).
Chapter 19 Enterprise Java Case Study: Business Logic Part 1 1083
Method addProduct (lines 39–108) adds a Product to the ShoppingCart. Lines
46–62 determine if the ShoppingCart already contains the given Product. If the
Product is found in the ShoppingCart, lines 56–57 increment the associated Order-
ProductModel’s quantity. Otherwise, method findByPrimaryKey of interface
ProductHome locates the Product with the given ISBN (line 77). Lines 84–85 create an
OrderProductModel to store the Product in the ShoppingCart. Line 87 adds the
ProductModel to the OrderProductModel, and line 88 sets the OrderProduct-
Model’s quantity to 1. Line 91 adds the OrderProductModel to the Collection,
which completes the addition of the Product to the ShoppingCart.
If method findByPrimaryKey of interface ProductHome does not find the
Product with the given primary key, lines 96–101 catch a FinderException. Lines
99–100 throw a ProductNotFoundException to indicate that a Product with the
given ISBN could not be found.
Method removeProduct (lines 111–139) compares the ISBN of each Product in
the ShoppingCart’s OrderProductModel Collection with the ISBN of the
Product to be removed. If the Product with the given ISBN is found, line 127 removes
the associated OrderProductModel from the Collection. If the Product is not
found in the ShoppingCart, lines 135–137 throw a ProductNotFoundExcep-
tion.
Method setProductQuantity (lines 142–180) sets the quantity of an
OrderProductModel in the ShoppingCart. If argument productQuantity is
less than 0, lines 147–148 throw an IllegalArgumentException. If the pro-
ductQuantity equals 0, line 152 removes the Product from the ShoppingCart.

Lines 158–173 compare the ISBN of each Product in the OrderProductModel
Collection with the given ISBN. Line 169 updates the matching OrderProduct-
Model’s quantity by invoking OrderProductModel method setQuantity. If
the Product with the given ISBN is not found in the ShoppingCart, lines 176–178
throw a ProductNotFoundException.
Method checkout (lines 183–232) places an Order for the Products in the
ShoppingCart. Each Order must have an associated Customer, so method
checkout takes the Customer’s userID as an argument. Lines 192–201 create an
OrderModel to represent the Order’s details. Each Order has an orderDate, a
shipped flag and a Collection of OrderProductModels. Line 195 sets the date
in the OrderModel. Line 198 invokes method setOrderProductModels of class
OrderModel to add the OrderProductModels list to the Order. Line 201 sets the
shipped flag to false, to indicate that the Order has not shipped from the warehouse.
We discuss entity EJB Order in detail in Section 19.5.
268 // passivate ShoppingCart EJB instance
269 public void ejbPassivate() {}
270
271 // remove ShoppingCart EJB instance
272 public void ejbRemove() {}
273 }
Fig. 19.3
Fig. 19.3Fig. 19.3
Fig. 19.3
ShoppingCartEJB implementation of ShoppingCart remote
interface (part 7 of 7).
1084 Enterprise Java Case Study: Business Logic Part 1 Chapter 19
Line 217 invokes method create of interface OrderHome to create a new Order.
Method create takes as arguments an OrderModel containing the details of the
Order to be created and a String containing the Customer’s userID. Line 220 emp-
ties the ShoppingCart by creating assigning a new ArrayList to Collection ref-

erence orderProductModels. Line 223 returns a remote reference to the newly
created Order. Lines 228–230 catch any exceptions that occur.
Method getTotal (lines 235–257) iterates through the Collection of Order-
ProductModels and calculates the total cost of items in the ShoppingCart.
19.3.3 ShoppingCartHome Interface
Interface ShoppingCartHome (Fig. 19.4) defines a single create method (lines 15–
16) that creates new ShoppingCart EJB instances. The EJB container provides the im-
plementation for method create.
Figure 19.5 and Figure 19.6 show the deployment settings for stateful session EJB
ShoppingCart. In addition to the settings shown here, be sure to set the Transaction
Type to Required for all business methods.
1 // ShoppingCartHome.java
2 // ShoppingCartHome is the home interface for stateful session
3 // EJB ShoppingCart.
4 package com.deitel.advjhtp1.bookstore.ejb;
5
6 // Java core packages
7 import java.rmi.RemoteException;
8
9 // Java extension packages
10 import javax.ejb.*;
11
12 public interface ShoppingCartHome extends EJBHome {
13
14 // create new ShoppingCart EJB
15 public ShoppingCart create()
16 throws RemoteException, CreateException;
17 }
Fig. 19.4
Fig. 19.4Fig. 19.4

Fig. 19.4
ShoppingCartHome interface for creating ShoppingCart EJB
instances.
ShoppingCart General Deployment Settings
Bean Type Stateful Session
Enterprise
Bean Class
com.deitel.advjhtp1.bookstore.ejb.ShoppingCartEJB
Fig. 19.5
Fig. 19.5Fig. 19.5
Fig. 19.5 ShoppingCart general deployment settings (part 1 of 2).

×