| [ directory ] |
JavaBeans would not have been mentioned if they were not commonly used with JSP and Servlets. There is no requirement mandating JavaBeans be used with JSP and Servlets, but the JSP standard actions and the JSP EL are a convenient way of using the beans for all levels of JSP developers. This is the primary reason JavaBeans are used as commonly as they are. Before looking at why this is the case, we need to see what exactly JSP provides as JavaBean standard actions.
The JSP standard actions, excluding the ones that relate to JavaBeans, were covered with JSP in Chapter 3. The JavaBean custom actions follow the same XML-compatible syntax and are also available for use with any JSP-compliant container. The actions are as described in the following sections.
The useBean action declares a JavaBean for use in a JSP. Once declared, the bean becomes a scripting variable that can be accessed by both scripting elements and other custom tags used in the JSP. The full syntax for the useBean tag is as follows:
<jsp:useBean id="bean's name" scope="bean's scope" typeSpec/>
The useBean action must always have two things specified: the bean's name and information about what class should be used. Optionally, the useBean action may also specify a particular scope for the declared JavaBean. The value of the id attribute may be any value as a long as it is a unique name among other useBean declarations in the same JSP. If the name is not unique, an exception is thrown by the JSP container at translation time of the JSP.
Valid values for the scope attribute are as follow:
page: The page value places the JavaBean as an attribute to the javax.servlet.jsp.PageContext for the current page. The bean is discarded upon completion of the current request.
request: The request value places the JavaBean in request scope. The JavaBean is available from the current page's ServletRequest object via the getAttribute() method. The JavaBean is discarded upon completion of the current request.
session: The session value places the JavaBean in session scope. The JavaBean can be accessed via the getAttribute() method of the HttpSession object associated with a client. The JavaBean automatically persists until the session is invalidated. A translation time error is raised if the session value is used on a JSP that has declared it is not participating in a session.
application: The application value places the JavaBean in application scope. The JavaBean persists as long as the application does and can be accessed via the getAttribute() method of the Web Application's ServletContext object.
Along with the id attribute and scope attribute, the useBean action needs to know what Java class should be initialized as the JavaBean. In most cases this is done by simply using the class or type attribute and specifying as a value the fully qualified Java class name. However, the useBean action also allows for any of the following combinations to be used when declaring what type of JavaBean is to be initialized.
class= className type= typeName class= className type= typeName beanName= beanName type= typeName
The attributes have the following meanings:
class: The class attribute must declare the fully qualified name of the class that defines the JavaBean. The class name is case sensitive. If the class and beanName attributes are not specified, an instance of the JavaBean must be present in the given scope.
beanName: The beanName attribute defines the name of a JavaBean, as expected by the instantiate() method of the java.beans.Beans class. The beanName attribute can be a runtime value specified by an expression.
type: The type attribute, if specified, defines the type of the scripting variable defined. This allows the type of the scripting variable to be distinct from, but related to, the type of the implementation class specified. The type is required to be either the class itself, a superclass of the class, or an interface implemented by the class specified. The object referenced is required to be of this type; otherwise, a java.lang.ClassCastException shall occur at request time. If the type attribute is unspecified, the value is the same as the value of the class attribute.
In the simplest of cases, a useBean action is equivalent to a scriptlet that declares a new instance of a variable as shown in Listing 5-2.
Consider the following use of the useBean action:
<html>
<head>
<title>useBean Example</title>
</head>
<body>
<jsp:useBean id="date" class="java.util.Date" />
The date/time is <%= date %>
</body>
</html>
Listing 5-3 could have easily been authored as the following code. The only difference between the two is that the preceding code does not require the use of a scriptlet.
<html>
<head>
<title>useBean Example</title>
</head>
<body>
<% java.util.Date date = new java.util.Date(); %>
The date/time is <%= date %>
</body>
</html>
This translation should help clarify what the useBean action is doing when declaring and using variables in the page scope of a JSP. By using the useBean action, no scriptlets are required on the JSP. The functionality is the same as if a scriptlet was used, but it is important to see that by using the useBean action, some scriptlets can be eliminated from the JSP. This concept is more important in the upcoming section where the getProperty and setProperty actions are introduced. With these actions it is possible to fully remove the need for scripting elements.
The useBean action actually does more than simply create a bean, which is what the previous code showed. The useBean action first checks if the bean already exists in this scope and if so reuses the existing bean. Scope checking makes the useBean action a convenient method of passing beans via request, session, or application scope and accessing them in a JSP. This is important functionality to be aware of, and it is what makes the useBean action a helpful standard action.
By applying the scope check to Listing 5-3, the scriptlet would really resemble something similar to Listing 5-4. In page scope it is redundant, but in request, session, and application scopes, the check is helpful.
<html>
<head>
<title>useBean Example</title>
</head>
<body>
<%
Object temp = pageContext.findAttribute("date");
java.util.Date tdate = null;
if (temp != null && temp instanceof java.util.Date) {
tdate = (java.util.Date) temp;
}
else {
tdate = new java.util.Date();
}
%>
The date/time is <%= tdate %>
</body>
</html>
It is important to note that the JavaBean is created only if the class attribute is used. If the type attribute alone is used, the JavaBean must already exist in the specified scope. Why is this considered necessary? In the design chapter, Chapter 11, the MVC pattern will be introduced. Using this design model a JSP and Servlet typically communicate by passing data in JavaBeans. A Servlet will typically create a JavaBean, store the bean in a particular scope, and then forward to the JSP. The JSP should only be called from the Servlet and should never have to create the JavaBean itself. To facilitate this, the type property should be used rather than class.
Complementing the useBean action are the getProperty and setProperty actions. The getProperty action provides a convenient way of invoking a get method, and the setProperty action provides a convenient way of invoking a set method. With all three of the bean-manipulating actions, it is now possible to remove the majority of scripting elements.
The getProperty action provides a way of removing many scriptlets and expressions. The action can be used to invoke a get method of a JavaBean and uses the following syntax.
<jsp:getProperty name="name" property="method" />
The name attribute references the name of a JavaBean previously introduced to the JSP by the useBean action. The property attribute is the name of the get method that should be invoked. The results of the get method are placed in the implicit out object after being converted to a string either by calling the toString() method or straight conversion in the case of primitives.
JavaBeans used by the getProperty action are found by invoking the PageContext findAttribute() method. A JavaBean previously set in a scope, such as request, session, or application, is not found unless useBean action has been used to make the bean visible to the JSP.
Consider the Java Bean in Listing 5-5. It is used as a simple data storage bean designed to hold information about a user.
package com.jspbook;
public class User {
protected String name = null;
protected String password = null;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
Save the preceding code as User.java in the /WEB-INF/classes/com/jspbook directory of the jspbook Web Application. The JavaBean is nothing special. It has a get and set method for the name and password variables. Combining the useBean and getProperty actions, the User bean is used on the following JSP. Save Listing 5-6 as getProperty.jsp in the root directory of the jspbook Web Application.
<html>
<head>
<title>useBean Example</title>
</head>
<body>
<jsp:useBean id="user" class="com.jspbook.User" />
<%
user.setName("Bob");
user.setPassword("password");
%>
Hello <jsp:getProperty name="user" property="name"/>, welcome to this web page!
</body>
</html>
Notice the name attribute of the getProperty action matches up with the id of the useBean action and the property attribute is name, not getName().The results of the getProperty action can be seen by then browsing to http://127.0.0.1/jspbook/getProperty.jsp. Figure 5-1 shows a browser rendering of the output.

The setProperty action is used to set values of a bean. The setProperty action uses similar attributes as the getProperty action but with the addition of a few new attributes. The syntax for the setProperty action is as follows.
<jsp:setProperty name="name" property="method" valueAttribute />
The name and property attributes are required and provide the name of the JavaBean and set method to be invoked on the bean. In addition to the name and property attributes, a value needs to be provided for a set method of the property's value. The value can be specified in one of two ways:
value="value"
The value attribute is used to set a given value as the parameter for the set method. The value of the value attribute may be a runtime value specified by a expression.
param="value"
A value can be retrieved from a request parameter. If the param attribute is used, the value of this attribute is used as the name of a request parameter. The value of the request parameter is used as the value for the bean's set method.
In the case where there are multiple parameters needing to be set as values of a JavaBean, the convenient * value may be specified. When * is used as the value of the param attribute, a one-to-one mapping is attempted between each request parameter to a set method of the same name.
Either one of the above methods may be used to provide a value for a set method. If both methods are used, a translation time error is raised.
With the useBean, getProperty, and setProperty actions, many scriptlets and expressions can be eliminated from a JSP. The only functionality the three actions cannot accomplish is iteration, or conditional evaluation, but in Chapter 6, the JSTL fills this deficiency. Listing 5-7 can be rewritten using the setProperty action as follows.
<html>
<head>
<title>useBean Example</title>
</head>
<body>
<jsp:useBean id="user" class="com.jspbook.User" />
<jsp:setProperty name="user" property="name" value="Bob"/>
<jsp:setProperty name="user" property="password" value="password"/>
Hello <jsp:getProperty name="user" property="name"/>, welcome to this web page!
</body>
</html>
The use of the setProperty action is straightforward. The scriptlet previously used in Listing 5-5 is replaced with two setProperty actions. In both uses of the setProperty action, the value attribute is used to specify a set, a String value. The JSP produces the same output shown in Figure 5-1 previously.
Typically, a JSP will not create JavaBeans. Many applications will be written using an MVC, or Model II, approach, in which case a Servlet will create the JavaBeans and JSP will reference them. However, for applications that use only a few JSP, beans are still useful. In these cases, in addition to creating beans, a JSP may need to initialize those beans.
Beans are Java objects with default constructors, which means that typically a bean will be created in a vanilla state. The bean may need to be initialized before use by calling the necessary set methods. To ensure a bean is properly initialized before use in a JSP, the JSP uses the jsp:useBean tag's body. Any code in the body of the tag is only executed when the bean is first created. So, for example, if a request comes into a JSP and that JSP has a useBean tag with request scope, that JSP will create the bean. If the useBean has a "body", that body will "execute". If the JSP then forwards to another JSP, and that JSP has a useBean tag for the same bean also with request scope, that bean will not be created. Just a reference will be retrieved from the request object. Even if that second useBean tag has a body, the body will not be executed. The body of the useBean tag is (morally) its constructor. An example is shown here
<jsp:useBean id="user" class="com.jspbook.User">
<jsp:setProperty name="user" property="name" value="Bob"/>
<jsp:setProperty name="user"
property="password"
value="password"/>
</jsp:useBean>
In this example, the user bean is in page scope. This means that whenever the page is executed, the bean will be created (remember that page scope means private to this page). Whenever a bean is created, its body is executed; that means the two setProperty calls will run and initialize the bean.
| [ directory ] |