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
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
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
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
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.";
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
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
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();
• 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
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
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
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 {
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 );
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
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)
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 {
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.
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