AJavaBean is a special type of Java class that you can use in several interesting ways to simplify program development. Some beans, such as Swing components, are designed to be visual components that you can use in a GUI editor to quickly build user interfaces. Other beans, known as Enterprise JavaBeans, 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 Java Server Pages. In a nutshell, you can use the simple JavaBeans to build Java Server 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.
Simply put, a JavaBean is any Java class that conforms to the following rules:
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.
REMEMBER |
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 allow them to have a visual interface so they can be used drag-and-drop style in an IDE. And some beans implement an interface that allows their state to be written to an output stream so 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 is covered in Book III, Chapter 2. Thus you've seen many examples of beans throughout this book, and you've probably written many bean classes yourself already.
REMEMBER |
Any class that conforms to this pattern is a bean. There's no JavaBean class you have to extend, nor is there a Bean interface you have to implement to be a bean. All a class has to do to be a bean is stick to the pattern. |
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.
TECHNICAL STAUFF |
In case you can't remember way back to high school, the long side is equal to the square root of the first short side squared plus the second short side squared. |
Listing 4-1: The Triangle Bean
package 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:
→ 1 |
As with most servlet classes, this bean is part of a package. In this case, the package is named 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.) |
→ 5 |
This class uses a pair of instance variables to keep track of the two short sides. As per the rules for JavaBeans, these instance variables are declared as private. |
→ 8 |
A constructor with no parameters is declared. (Strictly speaking, this constructor doesn't have to be explicitly coded here, because the default constructor does the trick, and the two instance variables are initialized to their default values of zero automatically.) |
→ 14 |
The getSideA method returns the value of the sideA property as a string. |
→ 19 |
The 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 zero. |
→ 31 |
The getSideB method returns the value of the sideB property as a string. |
→ 36 |
The 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 zero if the string can't be parsed to a double. |
→ 48 |
The getSideC method calculates the length of the long side, and then returns the result as a string. However, if either of the values is zero, 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. |
Open table as spreadsheet
Tip |
For an interesting anecdote about the Pythagorean Theorem and The Wizard of Oz, refer to Book III, Chapter 2. |
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.
Tag |
Description |
---|---|
name” class==“package.class” /> |
Establishes a reference to the bean and creates an instance if necessary. The name specified in the id attribute is used by the other tags to refer to the bean. |
name” property=“property” /> |
Retrieves the specified property from the bean identified by the name attribute. |
name” property=“property” value= =“value” /> |
Sets the specified property to the value specified in the value attribute. |
name” property=“property” param=parameter” /> |
Sets the specified property to the value of the parameter specified in the param” attribute. The parameter is usually the name of a form field. |
name” property=”* “/> |
Sets all the properties defined by the bean to corresponding parameter values, provided 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:
name" emphasis">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. For example, here's a jsp:useBean tag to use the Triangle bean:
The jsp:useBean tag creates an instance of the bean by calling the empty constructor if an instance doesn't already exist. However, if the bean already exists, the existing instance is used instead.
Here are a few additional things you should know about the jsp:useBean tag:
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.
To get the value of a bean's property, you use the jsp:getProperty tag. The form of this tag is straightforward:
For example, here's a tag that gets the sideC property from the Triangle bean created in the previous section:
The name attribute must agree with the value you specify in the id attribute in the jsp:useBean tag that created the bean. And the property attribute is used to determine the name of the getter method-in this case, getSideC.
Tip |
Remember to begin the property name with a lowercase letter. If you specify property=“SideC”, you get an error message from the server when you run the page. |
In most cases, you use jsp:getProperty to insert the value of a property into a page. However, you can also use it to specify the value of an attribute for some other tag in the JSP document. For example:
" >
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.
Warning |
Be extra careful to match up the quotation marks and the open and close brackets for the tags. In this example, the entire jsp:getProperty tag is enclosed within the quotation marks that indicate the value of the input field's value attribute. The right bracket that appears at the very end closes the input element itself. |
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:
Here the name attribute must match up to 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.
Tip |
I put this tag on three lines only because it's too long to fit within the margins of this page on one line. In actual practice, most JSP developers string these tags out on a single line unless they get really long, which doesn't happen often. |
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 into a form field or passed to the JSP by way of a query string. For example, 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:
Here, if the user enters a value into the FirstSide field, that value is assigned to the bean's sideA property.
In the previous example, I purposely used a name other than sideA for the input field so you wouldn'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:
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:
Here the asterisk (*) in the property attribute indicates that all properties that have names identical to form fields (or query string parameters) are automatically assigned. 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 that uses the bean that was presented in Listing 4-1. 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 it is run.
Figure 4-1: The Triangle. jsp page displayed in a browser.
Listing 4-2: The Triangle.jsp Page
→ 2 /> → 4Right Triangle Calculator
→ 10 Side A: → 12 value="" >
Side B: → 18 value="" >
Side C: → 24 property="sideC" />
→ 27
The following paragraphs explain the key lines in this JSP:
→ 2 |
The jsp:useBean tag creates an instance of the calculators.Triangle bean and names it triangle. |
→ 4 |
The jsp:setProperty tag sets the sideA and sideB properties to the corresponding input fields named sideA and sideB. |
→ 10 |
The form tag creates a form that posts back to the same JSP file using the HTTP POST method. |
→ 12 |
The first of two input text fields. This one is named sideA, and its initial value is set to the value of the bean's sideA property. |
→ 18 |
The second input text field is named sideB. Its initial value is set to the value of the bean's sideB property. |
→ 24 |
This line is where the 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. |
→ 27 |
The Submit button submits the form so the Triangle bean can do its thing. |
Open table as spreadsheet
The scope of a JavaBean indicates how long the bean is kept alive. You specify the scope by using the scope attribute on the jsp:useBean tag. The scope attribute can have any of the four values listed in Table 4-2.
Scope |
Explanation |
---|---|
page |
The bean is associated with the current page. Thus, every time the user requests the page, a new bean is created. Then, 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. |
request |
Similar to page, but the bean is available to other pages that are processed by the same request. This scope is useful for applications that use several different servlets or JSPs for a single request. |
session |
The bean is associated 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 other subsequent requests by the same user. |
application |
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. However, session scope 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 of that is a shopping cart, in which a user can select items 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 one. In the figure, the user has clicked the button for Networking All-in-One Desk Reference For Dummies twice and Networking For Dummies once.
Figure 4-2: A super-simple shopping cart application.
The following paragraphs describe the key techniques that make this shopping cart work:
Listing 4-3 shows the JSP for the shopping cart page.
Listing 4-3: BuyMyBook.jsp
→ 2 scope="session"/> → 4Buy My Books!
→ 10 method="post"> Networking For Dummies
→ 15 method="post"> Networking All-in-One Desk Reference For Dummies
→ 21 method="post"> Word 2003 All-In-One Desk Reference For Dummies
The following paragraphs describe the JSP's most important lines:
→ 2 |
The jsp:useBean tag loads the 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. |
→ 4 |
The parameter properties are set. The first time the user displays the 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. |
→ 10 |
This is the form for the first book. Each book has its own form, with a Submit button labeled 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. |
→ 15 |
The second book form. This one specifies netaio as the book parameter value. |
→ 21 |
The form for the third book. This one specifies wordaio as the value of the book parameter. |
→ 28 |
After the forms for each of the books, a jsp:getProperty tag calls the getList method of the bean. This returns a string that contains an HTML table that displays the current contents of the shopping cart. |
Open table as spreadsheet
Now that you've seen the JSP for the shopping cart application, take a look at the Java code for the BookCart bean. It's shown in Listing 4-4.
REMEMBER |
Listing 4-4 contains two classes-a BookCart class and an inner class named Book. So when you compile the code in Listing 4-4, you get two class files-BookCart.class and BookCart$Book.class. To run this application, you have to copy both class files to a Tomcat directory (a WEB-INFclassesooks directory). |
Listing 4-4: The BookCart JavaBean
package books; → 1 import java.util.ArrayList; import java.text.NumberFormat; public class BookCart { private ArrayList cart; → 8 private NumberFormat cf = NumberFormat.getCurrencyInstance(); public BookCart() → 13 { cart = new ArrayList(); } 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 = ""; list +="" + ""; double total = 0.0; for (Book b : cart) { list += "" + "" + "" + "" + ""; total += b.getTotal(); } list +="" + ""; list += "
Title | Qty | Price | Total |
" + b.getTitle() + " | " + b.getQuantity() + " | " + cf.format(b.getPrice()) + " | " + cf.format(b.getTotal()) + " |
Total: | " + cf.format(total) + " |
"; 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("netfd")) return "Networking For Dummies"; else if (code.equals("netaio")) return "Networking All-in-One Desk " + "Reference For Dummies"; else if (code.equals("wordaio")) return "Word 2003 All-in-One Desk " + "Reference For Dummies"; else return "Unknown book"; } public double getPrice() → 82 { if (code.equals("netfd")) return 24.99; else if (code.equals("netaio")) return 34.99; else if (code.equals("wordaio")) 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:
and tags mark the start and end of each row, and the 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.
→ 1 |
The BookCart class lives in the books package. |
→ 8 |
The shopping cart itself is kept inside the BookCart bean as a private array list of Book items. |
→ 13 |
To be a JavaBean, you need a no-parameter constructor. This one simply initializes the cart array list. |
→ 18 |
The 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 if 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 |
and | |
→ 52 |
The Book class is defined as an inner class so it can represent books in the array list. |
→ 54 |
The Book class only stores two items of information for each book: the book code and the quantity, which represents the number of books ordered by the user. The other values are calculated by the methods that return them. |
→ 57 |
The constructor accepts a book code and initializes the instance fields. Notice that the quantity is initialized to 1. |
→ 63 |
The getCode method simply returns the code variable. |
→ 68 |
The getTitle method returns one of three book titles depending on the code. If the code is not one of the three pre-defined codes, Unknown book is returned. |
→ 82 |
Likewise, the 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! |
→ 94 |
The getQuantity method just returns the quantity variable. |
→ 99 |
The addQuantity method adds a value to the quantity variable. |
→ 104 |
The getTotal method calculates the total by multiplying the price by the quantity. |
Open table as spreadsheet
Book I - Java Basics
Book II - Programming Basics
Book III - Object-Oriented Programming
Book IV - Strings, Arrays, and Collections
Book V - Programming Techniques
Book VI - Swing
Book VII - Web Programming
Book VIII - Files and Databases
Book IX - Fun and Games