JavaBeans Components in JSP Pages
Overview
JavaBeans component design conventions govern the properties of the class and govern the public methods that give access to the properties.
A JavaBeans component property can be
- Read/write, read-only, or write-only
- Simple, which means it contains a single value, or indexed, which means it represents an array of values
There is no requirement that a property be implemented by an instance variable; the property must simply be accessible using public methods that conform to certain conventions:
- For each readable property, the bean must have a method of the form
PropertyClass getProperty() { ... }- For each writable property, the bean must have a method of the form
setProperty(PropertyClass pc) { ... }In addition to the property methods, a JavaBeans component must define a constructor that takes no parameters.
The Duke's Bookstore application JSP pages enter.jsp, bookdetails.jsp, catalog.jsp, and showcart.jsp use the database.BookDB and database.BookDetails JavaBeans components. BookDB provides a JavaBeans component front end to the access object BookDBAO. Both beans are used extensively by bean-oriented custom tags (see Custom Tags in JSP Pages). The JSP pages showcart.jsp and cashier.jsp use cart.ShoppingCart to represent a user's shopping cart.
The JSP pages catalog.jsp, showcart.jsp, and cashier.jsp use the util.Currency JavaBeans component to format currency in a locale-sensitive manner. The bean has two writable properties, locale and amount, and one readable property, format. The format property does not correspond to any instance variable, but returns a function of the locale and amount properties.
public class Currency { private Locale locale; private double amount; public Currency() { locale = null; amount = 0.0; } public void setLocale Locale(l) { locale = l; } public void setAmount(double a) { amount = a; } public String getFormat() { NumberFormat nf = NumberFormat.getCurrencyInstance(locale); return nf.format(amount); } }Why Use a JavaBeans Component?
A JSP page can create and use any type of Java programming language object within a declaration or scriptlet. The following scriptlet creates the bookstore shopping cart and stores it as a session attribute:
<% ShoppingCart cart = (ShoppingCart)session. getAttribute("cart"); // If the user has no cart, create a new one if (cart == null) { cart = new ShoppingCart(); session.setAttribute("cart", cart); } %>If the shopping cart object conforms to JavaBeans conventions, JSP pages can use JSP elements to create and access the object. For example, the Duke's Bookstore pages bookdetails.jsp, catalog.jsp, and showcart.jsp replace the scriptlet with the much more concise JSP useBean element:
<jsp:useBean id="cart" class="cart.ShoppingCart" scope="session"/>Creating and Using a JavaBeans Component
You declare that your JSP page will use a JavaBeans component using either one of the following formats:
<jsp:useBean id="beanName" class="fully_qualified_classname" scope="scope"/>or
<jsp:useBean id="beanName" class="fully_qualified_classname" scope="scope"> <jsp:setProperty .../> </jsp:useBean>The second format is used when you want to include jsp:setProperty statements, described in the next section, for initializing bean properties.
The jsp:useBean element declares that the page will use a bean that is stored within and accessible from the specified scope, which can be application, session, request, or page. If no such bean exists, the statement creates the bean and stores it as an attribute of the scope object (see Using Scope Objects). The value of the id attribute determines the name of the bean in the scope and the identifier used to reference the bean in other JSP elements and scriptlets.
Note: In JSP Scripting Elements, we mentioned that import any classes and packages used by a JSP page. This rule is slightly altered if the class is only referenced by useBean elements. In these cases, only import the class if the class is in the unnamed package. For example, in What Is a JSP Page?, the page index.jsp imports the MyLocales class. However, in the Duke's Bookstore example, all classes are contained in packages and thus are not explicitly imported.
The following element creates an instance of Currency if none exists, stores it as an attribute of the session object, and makes the bean available throughout the session by the identifier currency:
<jsp:useBean id="currency" class="util.Currency" scope="session"/>Setting JavaBeans Component Properties
There are two ways to set JavaBeans component properties in a JSP page: with the jsp:setProperty element or with a scriptlet
<% beanName.setPropName(value); %>The syntax of the jsp:setProperty element depends on the source of the property value. Table 14-1 summarizes the various ways to set a property of a JavaBeans component using the jsp:setProperty element.
Value Source
Element Syntax
String constant
<jsp:setProperty name="beanName"
property="propName" value="string constant"/>
Request parameter
<jsp:setProperty name="beanName"
property="propName" param="paramName"/>
Request parameter name matches bean property
<jsp:setProperty name="beanName"
property="propName"/>
<jsp:setProperty name="beanName"
property="*"/>
Expression
<jsp:setProperty name="beanName"
property="propName"
value="<%= expression %>"/>
1. beanName must be the same as that specified for the id attribute in a useBean element.
2. There must be a setPropName method in the JavaBeans component.
3. paramName must be a request parameter name.
A property set from a constant string or request parameter must have a type listed in Table 14-2. Since both a constant and request parameter are strings, the Web container automatically converts the value to the property's type; the conversion applied is shown in the table. String values can be used to assign values to a property that has a PropertyEditor class. When that is the case, the setAsText(String) method is used. A conversion failure arises if the method throws an IllegalArgumentException. The value assigned to an indexed property must be an array, and the rules just described apply to the elements.
Property Type
Conversion on String Value
Bean Property
Uses setAsText(string-literal)
boolean or Boolean
As indicated in java.lang.Boolean.valueOf(String)
byte or Byte
As indicated in java.lang.Byte.valueOf(String)
char or Character
As indicated in java.lang.String.charAt(0)
double or Double
As indicated in java.lang.Double.valueOf(String)
int or Integer
As indicated in java.lang.Integer.valueOf(String)
float or Float
As indicated in java.lang.Float.valueOf(String)
long or Long
As indicated in java.lang.Long.valueOf(String)
short or Short
As indicated in java.lang.Short.valueOf(String)
Object
new String(string-literal)
You would use a runtime expression to set the value of a property whose type is a compound Java programming language type. Recall from Expressions that a JSP expression is used to insert the value of a scripting language expression, converted into a String, into the stream returned to the client. When used within a setProperty element, an expression simply returns its value; no automatic conversion is performed. As a consequence, the type returned from an expression must match or be castable to the type of the property.
The Duke's Bookstore application demonstrates how to use the setProperty element and a scriptlet to set the current book for the database helper bean. For example, bookstore3/web/bookdetails.jsp uses the form:
<jsp:setProperty name="bookDB" property="bookId"/>whereas bookstore2/web/bookdetails.jsp uses the form:
<% bookDB.setBookId(bookId); %>The following fragments from the page bookstore3/web/showcart.jsp illustrate how to initialize a currency bean with a Locale object and amount determined by evaluating request-time expressions. Because the first initialization is nested in a useBean element, it is only executed when the bean is created.
<jsp:useBean id="currency" class="util.Currency" scope="session"> <jsp:setProperty name="currency" property="locale" value="<%= request.getLocale() %>"/> </jsp:useBean> <jsp:setProperty name="currency" property="amount" value="<%=cart.getTotal()%>"/>Retrieving JavaBeans Component Properties
There are several ways to retrieve JavaBeans component properties. Two of the methods (the jsp:getProperty element and an expression) convert the value of the property into a String and insert the value into the current implicit out object:
- <jsp:getProperty name="beanName" property="propName"/>
- <%= beanName.getPropName() %>
For both methods, beanName must be the same as that specified for the id attribute in a useBean element, and there must be a getPropName method in the JavaBeans component.
If you need to retrieve the value of a property without converting it and inserting it into the out object, use a scriptlet:
<% Object o = beanName.getPropName(); %>Note the differences between the expression and the scriptlet; the expression has an = after the opening % and does not terminate with a semicolon, as does the scriptlet.
The Duke's Bookstore application demonstrates how to use both forms to retrieve the formatted currency from the currency bean and insert it into the page. For example, bookstore3/web/showcart.jsp uses the form
<jsp:getProperty name="currency" property="format"/>whereas bookstore2/web/showcart.jsp uses the form:
<%= currency.getFormat() %>The Duke's Bookstore application page bookstore2/web/showcart.jsp uses the following scriptlet to retrieve the number of books from the shopping cart bean and open a conditional insertion of text into the output stream:
<% // Print a summary of the shopping cart int num = cart.getNumberOfItems(); if (num > 0) { %>Although scriptlets are very useful for dynamic processing, using custom tags (see Custom Tags in JSP Pages) to access object properties and perform flow control is considered to be a better approach. For example, bookstore3/web/showcart.jsp replaces the scriptlet with the following custom tags:
<bean:define id="num" name="cart" property="numberOfItems" /> <logic:greaterThan name="num" value="0" >Figure 14-1 summarizes where various types of objects are stored and how those objects can be accessed from a JSP page. Objects created by the jsp:useBean tag are stored as attributes of the scope objects and can be accessed by jsp:[get|set]Property tags and in scriptlets and expressions. Objects created in declarations and scriptlets are stored as variables of the JSP page's servlet class and can be accessed in scriptlets and expressions.
Figure 14-1 Accessing Objects From a JSP Page