Chapter 4
IN THIS CHAPTER
Defining JavaBeans
Creating your own JavaBean classes
Using JavaBeans in JSP pages
Creating a simple shopping cart with session scope
A JavaBean is a special type of Java class that you can use in several interesting ways to simplify program development. Some beans are designed to be visual components that you can use in a graphic user interface (GUI) editor to build user interfaces quickly. Other beans, known as Enterprise JavaBeans (EJB), are designed to run on special EJB servers and can run the data access and business logic for large web applications.
In this chapter, I look at a more modest type of JavaBean that’s designed to simplify the task of building JavaServer Pages (or JSP, which I cover in Book 7, Chapter 3). In a nutshell, you can use the simple JavaBeans to build JavaServer Pages without writing any Java code in the JSP itself. JavaBeans let you access Java classes by using special HTML-like tags in the JSP page.
To use JavaBeans, you must have Tomcat enabled. For more information about installing and configuring Tomcat, please refer to Book 7, Chapter 2.
Simply put, a JavaBean is any Java class that conforms to the following rules:
public
instance variables. All the instance variables defined by the class must be either private
or protected
.It must provide methods named get
Property and set
Property to get and set the value of any properties the class provides, except for boolean
properties that use is
Property to get the property value. The term property isn’t an official Java term. In a nutshell (or should that be in a beanpod?), a property is any value of an object that can be retrieved by a get
method (or an is
method, if the property is boolean
) or set with a set
method. If a class has a property named lastName
, for example, it should use a method named getLastName
to get the last name and setLastName
to set the last name. Or, if the class has a boolean
property named taxable
, the method to set it is called setTaxable
, and the method to retrieve it is isTaxable
.
Note that a class doesn’t have to have any properties to be a JavaBean, but if it does, the properties have to be accessed according to this naming pattern. Also, not all properties must have both a get
and a set
accessor. A read-only property can have just a get
accessor, and a write-only property can have just a set
accessor.
The property name is capitalized in the methods that access it, but the property name itself isn’t. Thus setAddress
sets a property named address
, not Address
.
That’s all there is to it. More advanced beans can also have other characteristics that give them a visual interface so that they can be used drag-and-drop style in an integrated development environment (IDE). Also, some beans implement an interface that allows their state to be written to an output stream so that they can be re-created later. But those features are optional; any class that meets the three criteria stated here is a bean and can be used as a bean in JSP pages.
You’ve already seen plenty of classes that have methods with names like getCount
and setStatus
. These names are part of a design pattern called the Accessor pattern, which I cover in Book 3, Chapter 2. Thus you’ve seen many examples of beans throughout this book, and you’ve probably written many bean classes yourself already.
Listing 4-1 shows a sample JavaBean class named Triangle
that calculates the Pythagorean Theorem, which calculates the long side of a right triangle if you know the length of the two short sides. This class defines three properties: sideA
and sideB
represent the two short sides of the triangle, and sideC
represents the long side. The normal way to use this bean is to first use the setSideA
and setSideB
methods to set the sideA
and sideB
properties to the lengths of the short sides and then use the getSideC
method to get the length of the long side.
LISTING 4-1 The Triangle Bean
package com.lowewriter.calculators; →1
public class Triangle
{
private double sideA; →5
private double sideB;
public Triangle() →8
{
this.sideA = 0.0;
this.sideB = 0.0;
}
public String getSideA() →14
{
return Double.toString(this.sideA);
}
public void setSideA(String value) →19
{
try
{
this.sideA = Double.parseDouble(value);
}
catch (Exception e)
{
this.sideA = 0.0;
}
}
public String getSideB() →31
{
return Double.toString(this.sideB);
}
public void setSideB(String value) →36
{
try
{
this.sideB = Double.parseDouble(value);
}
catch (Exception e)
{
this.sideB = 0.0;
}
}
public String getSideC() →48
{
if (sideA == 0.0 || sideB == 0.0)
return "Please enter both sides.";
else
{
Double sideC;
sideC = Math.sqrt(
(sideA * sideA) + (sideB * sideB));
return Double.toString(sideC);
}
}
}
The following paragraphs point out the highlights of this bean class:
com.lowewriter.calculators
. (I’m assuming that if you need a bean to calculate the Pythagorean theorem, you probably want other beans to calculate derivatives, prime numbers, Demlo numbers, and the like. You can put those beans in this package, too.)private
.0
automatically.)getSideA
method returns the value of the sideA
property as a string.setSideA
method lets you set the value of the sideA
property with a string. This method uses a try
/catch
statement to catch the exceptions that are thrown if the string can’t be parsed to a double
. If the string is invalid, the sideA
property is set to 0
.getSideB
method returns the value of the sideB
property as a string.setSideB
method sets the value of the sideB
property from a string. Again, a try
/catch
statement catches any exceptions and sets the property to 0
if the string can’t be parsed to a double
.getSideC
method calculates the length of the long side and then returns the result as a string. If either of the values is 0
, however, the method assumes that the user hasn’t entered any data, so it returns an error message instead. (That’s a reasonable assumption, because none of the sides of a triangle can be zero.) Notice that there is no setSideC
method. As a result, sideC
is a read-only property.To work with a bean in a JSP page, you add special tags to the page to create the bean, set its properties, and retrieve its properties. Table 4-1 lists these tags, and the following sections describe the details of using each one.
TABLE 4-1 JSP Tags for Working with Beans
Tag |
Description |
|
Establishes a reference to the bean and creates an instance if necessary. The name specified in the |
|
Retrieves the specified property from the bean identified by the |
|
Sets the specified property to the value specified in the |
|
Sets the specified property to the value of the parameter specified in the |
|
Sets all the properties defined by the bean to corresponding parameter values, provided that a parameter with the correct name exists. |
To include a bean in a JSP page, you add a special jsp:useBean
tag to the page. In its simplest form, this tag looks like this:
<jsp:useBean id="name" class="package.Class" />
The id
attribute provides the name that you use elsewhere in the JSP to refer to the bean, and the class
attribute provides the name of the class, qualified with the package name. Here’s a jsp:useBean
tag to use the Triangle
bean:
<jsp:useBean id="triangle"
class="com.lowewriter.calculators.Triangle" />
The jsp:useBean
tag creates an instance of the bean by calling the empty constructor if an instance doesn’t already exist. If the bean does already exist, the existing instance is used instead.
Here are a few additional things you should know about the jsp:useBean
tag:
jsp:useBean
tag can appear anywhere in the JSP document, but it must appear before any other tag that refers to the bean.<jsp:usebean…/>
won’t work.WEB-INFclasses
that’s named the same as the package. You might store the Triangle
bean’s class file in WEB-INFclassescalculators
, for example. (For more info on Tomcat, flip to Book 7, Chapter 2.)jsp:useBean
element can have a body containing jsp:setProperty
tags that initialize property values. Then the element is formed more like normal HTML, with proper start and end tags, as in this example:
<jsp:useBean id="t1" class="com.lowewriter.calculators.Triangle" >
<jsp:setProperty name="t1" property="sideA" value="3.0" >
<jsp:setProperty name="t1" property="sideB" value="3.0" >
</jsp:useBean>
Don’t worry about the details of the jsp:setProperty
tags just yet. Instead, just make a note that they’re executed only if a new instance of the bean is actually created by the jsp:useBean
tag. If an instance of the bean already exists, the jsp:setProperty
tags are not executed.
jspuseBean
tag also has a scope
attribute, which I explain in the section “Scoping Your Beans,” later in this chapter.To get the value of a bean’s property, you use the jsp:getProperty
tag. The form of this tag is straightforward:
<jsp:getProperty name="name" property="property" />
Here’s a tag that gets the sideC
property from the Triangle
bean created in the preceding section:
<jsp:getProperty name="triangle" property="sideC" />
The name
attribute must agree with the value you specify in the id
attribute of the jsp:useBean
tag that created the bean. Also, the property
attribute is used to determine the name of the getter method — in this case, getSideC
.
In most cases, you use jsp:getProperty
to insert the value of a property into a page, but you can also use it to specify the value of an attribute for some other tag in the JSP document, as in this example:
<input type="text" name="sideA"
value="<jsp:getProperty name="triangle"
property="sideA" />" >
Here the value of the sideA
property is retrieved and used for the value
attribute of an input field named sideA
. As a result, when this input field is sent to the browser, its initial value is the value from the Triangle
bean.
To set a property value, you can use one of several variations of the jsp:setProperty
tag. If you want to set the property to a literal string, you write the tag like this:
<jsp:setProperty name="triangle"
property="sideA"
value="4.0" />
Here the name
attribute must match the id
attribute from the jsp:useBean
tag that created the bean; the property
attribute is used to determine the name of the setter method (in this case, setSideA
); and the value
attribute provides the value to be set.
Although this form of the jsp:setProperty
tag is useful, the param
form is more useful. It lets you set the property to the value entered by the user in a form field or passed to the JSP by way of a query string. If your JSP contains a form that has an input field named FirstSide
, you can assign that field’s value to the sideA
property like this:
<input type="text" name="FirstSide" >
<jsp:setProperty name="triangle"
property="sideA"
param="FirstSide" />
Here, if the user enters a value in the FirstSide
field, that value is assigned to the bean’s sideA
property.
In the preceding example, I deliberately use a name other than sideA
for the input field so that you won’t be confused by the fact that the property
and param
attributes specify the same value. In actual practice, you usually give the input field the same name as the property it’s associated with, like this:
<input type="text" name="sideA" >
<jsp:setProperty name="triangle"
property="sideA"
param="sideA" />
If your input fields have names that are identical to the property names, you can assign all of them to their corresponding properties with one tag, like this:
<jsp:setProperty name="triangle" property="*" />
Here the asterisk (*
) in the property
attribute indicates that all properties that have names identical to form fields (or query-string parameters) are assigned automatically. For forms that have a lot of fields, this form of the jsp:setProperty
tag can save you a lot of coding.
So that you can see how these tags work together, Listing 4-2 shows a complete JSP page using the bean that was presented in Listing 4-2. This page displays two text input fields and a button. When the user enters the lengths of a triangle’s two short sides in the fields and clicks the button, the page displays the sideC
property of the bean to show the length of the third side. Figure 4-1 shows how this page appears when the code is run.
LISTING 4-2 The Triangle.jsp Page
<html>
<jsp:useBean id="triangle" →2
class="com.lowewriter.calculators.Triangle" />
<jsp:setProperty name="triangle" property="*" /> →4
<head>
<title>Right Triangle Calculator</title>
</head>
<body>
<h1>The Right Triangle Calculator</h1>
<form action="Triangle.jsp" method="post"> →10
Side A:
<input type="text" name="sideA" →12
value="<jsp:getProperty
name="triangle"
property="sideA" />" >
<br><br>
Side B:
<input type="text" name="sideB" →18
value="<jsp:getProperty
name="triangle"
property="sideB" />" >
<br><br>
Side C:
<jsp:getProperty name="triangle" →24
property="sideC" />
<br><br>
<input type="submit" value="Calculate" > →27
</form>
</body>
</html>
The following paragraphs explain the key lines in this JSP:
jsp:useBean
tag creates an instance of the calculators.Triangle
bean and names it triangle
.jsp:setProperty
tag sets the sideA
and sideB
properties to the corresponding input fields named sideA
and sideB
.form
tag creates a form that posts back to the same JSP file using the HTTP POST
method.sideA
, and its initial value is set to the value of the bean’s sideA
property.sideB
. Its initial value is set to the value of the bean’s sideB
property.sideC
property is retrieved, thus calculating the length of side C of the triangle based on the length of sides A and B. The result is simply inserted into the document.Triangle
bean can do its thing.The scope of a JavaBean indicates how long the bean is kept alive. You specify the scope by using the scope
attribute of the jsp:useBean
tag. The scope
attribute can have any of the four values listed in Table 4-2.
TABLE 4-2 Scope Settings
Scope |
Explanation |
|
This setting associates the bean with the current page. Thus, every time the user requests the page, a new bean is created. When the page is sent back to the browser, the bean is destroyed. Thus each round trip to the server creates a new instance of the bean. |
|
This setting is similar to |
|
This setting associates the bean with a user’s session. The first time the user requests a page from the application, a bean is created and associated with the user. Then the same bean is used for subsequent requests by the same user. |
|
This setting means that a single copy of the bean is used by all users of the application. |
The default scope is page
, which means that the bean is created and destroyed each time the user requests a new page. The session
scope, however, can be very useful for web applications that need to keep track of information about a user from one page to the next. The best-known example is a shopping cart, in which a user can select items that he or she wants to purchase. The contents of the shopping cart can be kept in a session bean.
Figure 4-2 shows a simple shopping cart application in which the user has the option to purchase three of my recent books by clicking one of the three buttons. When the user clicks a button, an item is added to the shopping cart. If the user has already added the book to the cart, the quantity is increased by 1. In the figure, the user has clicked the button for Electronics All-in-One For Dummies once and the button for Networking All-in-One For Dummies twice.
The following paragraphs describe the key techniques that make this shopping cart work:
setBook
, which adds a book to the shopping cart, and getList
, which returns a string that shows the shopping cart items nicely formatted in an HTML table.Book
object. To keep the application simple, the Book
class has the three titles hard-coded into it. In a real shopping cart program, you use a file or database instead of hard-coding these values.book
, and its value is the code of the book the user ordered. This parameter is bound to the book
property of the shopping cart bean, so when the user clicks one of the buttons, the setBook
method is called with the value passed via the book
parameter. That’s how the shopping cart knows which book the user ordered.jsp:getProperty
tag to get the list
property, which displays the shopping cart.Listing 4-3 shows the JSP for the shopping cart page.
LISTING 4-3 BuyMyBook.jsp
<html>
<jsp:useBean id="cart" →2
class="com.lowewriter.books.BookCart" scope="session"/>
<jsp:setProperty name="cart" property="*" /> →4
<head>
<title>Buy My Books!</title>
</head>
<body>
<h1>Which of my books do you want to buy?</h1>
<form action="BuyMyBook.jsp?book=elecaio" →10
method="post">
<input type="submit" value="Buy" >
Electronics All-in-One For Dummies<br><br>
</form>
<form action="BuyMyBook.jsp?book=netaio" →15
method="post">
<input type="submit" value="Buy" >
Networking All-in-One Desk Reference
For Dummies
<br><br>
</form>
<form action="BuyMyBook.jsp?book=wordaio" →21
method="post">
<input type="submit" value="Buy" >
Java All-in-One Desk Reference For Dummies
<br><br>
</form>
<br><h2>Your cart contains:</h2>
<jsp:getProperty name="cart" property="list" /> →28
</body>
</html>
The following paragraphs describe the JSP’s most important lines:
jsp:useBean
tag loads the com.lowewriter.books.BookCart
JavaBean, specifying that it has session scope. Thus, the bean isn’t deleted after each page is requested. Instead, the user works with the same bean instance for his or her entire session.BuyMyBook.jsp
page, there are no parameters, so this method doesn’t do anything. But when the user clicks one of the three form buttons, a book
parameter is added to the end of the URL that’s posted to the server, so the cart’s setBook
method is called. This causes one copy of the selected book to be added to the cart.Buy
and a book title. The action
attribute specifies that when the Submit button is clicked, the form is posted to BuyMyBook.jsp
with the book
parameter set to netfd
.netaio
as the book
parameter value.wordaio
as the value of the book
parameter.jsp:getProperty
tag calls the getList
method of the bean. This method returns a string containing an HTML table that displays the current contents of the shopping cart.Now that you’ve seen the JSP for the shopping cart application, take a look at the Java code for the BookCart
bean, shown in Listing 4-4.
LISTING 4-4 The BookCart JavaBean
package com.lowewriter.books; →1
import java.util.ArrayList;
import java.text.NumberFormat;
public class BookCart
{
private ArrayList<Book> cart; →8
private NumberFormat cf
= NumberFormat.getCurrencyInstance();
public BookCart() →13
{
cart = new ArrayList<Book>();
}
public void setBook(String code) →18
{
boolean found = false;
for (Book b : cart)
if (b.getCode().equals(code))
{
b.addQuantity(1);
found = true;
}
if (!found)
cart.add(new Book(code));
}
public String getList() →31
{
String list = "<table border=2>";
list +="<tr><td>Title</td><td>Qty</td>"
+ "<td>Price</td><td>Total</td></tr>";
double total = 0.0;
for (Book b : cart)
{
list += "<tr><td>"
+ b.getTitle() + "</td>"
+ "<td>" + b.getQuantity() + "</td>"
+ "<td>" + cf.format(b.getPrice())
+ "</td>"
+ "<td>" + cf.format(b.getTotal())
+ "</td>"
+ "</tr>";
total += b.getTotal();
}
list +="<tr><td></td><td></td><td>Total:</td>"
+ "<td>" + cf.format(total)
+ "</td></tr>";
list += "</table>";
return list;
}
private class Book →52
{
private String code; →54
private int quantity;
public Book(String code) →57
{
this.code = code;
this.quantity = 1;
}
public String getCode() →63
{
return this.code;
}
public String getTitle() →68
{
if (code.equals("elecaio"))
return "Electronics All-in-One For Dummies";
else if (code.equals("netaio"))
return "Networking All-in-One For Dummies";
else if (code.equals("javaaio"))
return "Java All-in-One For Dummies";
else
return "Unknown book";
}
public double getPrice() →82
{
if (code.equals("elecaio"))
return 34.99;
else if (code.equals("netaio"))
return 22.99;
else if (code.equals("javaaio"))
return 29.99;
else
return 0.0;
}
public int getQuantity() →94
{
return this.quantity;
}
public void addQuantity(int qty) →99
{
this.quantity += qty;
}
public double getTotal() →104
{
return this.quantity * this.getPrice();
}
}
}
The following paragraphs describe the bean’s high points:
BookCart
class lives in the books
package.BookCart
bean as a private array list of Book
items.cart
array list.setBook
method is called to add a book to the shopping cart. The book’s code is passed as a parameter. This method first looks at all the books in the array list to see whether the user has already added a book with this code. If so, that book’s addQuantity
method is called to increase the order quantity for that book by 1. If not, a new book with the specified code is created and added to the cart.→31 This method builds a string that contains all the books in the cart presented as an HTML table. If you’re not familiar with HTML tables, all you really need to know is that the <tr>
and </tr>
tags mark the start and end of each row, and the <td>
and </td>
tags mark the start and end of each cell within the row. The table includes one row for each book in the cart. Each row contains cells for the title, quantity, price, and total. If you compare the code in this method with the actual table shown in Figure 4-2, you can get an idea of the HTML that’s actually created by this method.
Notice also that the loop that builds each table row keeps a running total for the entire shopping cart, which is displayed in a separate row at the bottom of the table. Also, a row of headings is displayed at the start of the table.
Book
class is defined as an inner class so that it can represent books in the array list.Book
class stores only two items of information for each book: the book code and the quantity. The latter represents the number of books ordered by the user. The other values are calculated by the methods that return them.1
.getCode
method simply returns the code
variable.getTitle
method returns one of three book titles, depending on the code. If the code is not one of the three predefined codes, Unknown book
is returned.getPrice
method returns one of three prices, depending on the code. If the code is not one of the three allowable codes, the book is free!getQuantity
method just returns the quantity
variable.addQuantity
method adds a value to the quantity
variable.