18.5 JSP and JavaBeans

Java Servlet Programming, 2nd Edition > 18. JavaServer Pages > 18.5 JSP and JavaBeans

 
< BACKCONTINUE >

18.5 JSP and JavaBeans

One of the most interesting and powerful ways to use JavaServer Pages is in cooperation with JavaBeans components. JavaBeans are reusable Java classes whose methods and variables follow specific naming conventions to give them added abilities. They can be embedded directly in a JSP page using the <jsp:useBean> tag, or what JSP calls an action. A JavaBean component can perform a well-defined task (execute database queries, connect to a mail server, maintain information about the client, etc.) and make its resulting information available to the JSP page through simple accessor methods. For more information on JavaBeans, see http://java.sun.com/bean and the book Developing Java Beans by Robert Englander (O'Reilly).

The difference between a JavaBeans component embedded in a JSP page and a normal third-party class used by the generated servlet is that the web server can give JavaBeans embedded in a page special treatment. For example, a server can automatically set a bean's properties (essentially instance variables) using the parameter values in the client's request. In other words, if the request includes a name parameter and the server detects through introspection (a technique in which the methods and variables of a Java class can be programmatically determined at runtime) that the bean has a name property and a setName(String name) method, the server can automatically call setName( ) with the value of the name parameter. There's no need for getParameter( ).

A bean can also have its scope managed automatically by the server. A bean can be assigned to a specific page (where it is used once and destroyed), a specific request (similar to page scope except the bean persists between internal include and forward calls), to a client session (where the bean is automatically made available every time the same client reconnects), or to an application scope (where the same bean is available to the entire web application).

18.5.1 Embedding a Bean

Beans are embedded in a JSP page using the <jsp:useBean> action. It has the following syntax (case sensitive, and the quotes are mandatory):

<jsp:useBean  scope="page|request|session|application"               type="typeName"> </jsp:useBean>

You can set the following attributes of the <jsp:useBean> action:

id

Specifies the name of the bean. This is the key under which the bean is saved if its scope extends beyond the page. If a bean instance saved under this name already exists in the given scope, that instance is used with this page. Otherwise a new bean is created. For example:

scope

Specifies the scope of the bean's visibility. The value must be page, request, session, or application. If page, the variable is created essentially as an instance variable; if request, the variable is stored as a request attribute; if session, the bean is stored in the user's session; and if application, the bean is stored in the servlet context. For example:

scope="session"

The default value is page.

class

Specifies the class name of the bean. This is used when initially constructing the bean. The class name must be fully qualified. For example:

 

The class attribute is not necessary if the bean already exists in the current scope, but there must still be a type attribute to allow the system to cast the object to the proper type. If there's a problem constructing the given class, the JSP page throws an InstantiationException.

type

Specifies the type of the bean as it should be held by the system, used for casting when the object is retrieved from the request, session, or context. The type value should be the fully qualified name of a superclass or an interface of the actual class. For example:

type="com.company.tracking.UserPreferences"

If unspecified, the value defaults to be the same as the class attribute. If the type does not match the object's true type, the JSP page throws a ClassCastException.

beanName

The class attribute may be replaced by a beanName attribute. The difference between the two is that beanName uses Beans.instantiate( ) to create the bean instance, which looks for a serialized version of the bean (a .ser file) before creating an instance from scratch. This allows the use of preconfigured beans. See the Beans.instantiate( ) Javadoc documentation for more information. For example:

beanName="com.company.tracking.UserPreferencesImpl"

The body of the <jsp:useBean> element everything between the opening <jsp:useBean> and the closing </jsp:useBean> is interpreted after the bean's creation. If the bean is not created (because an existing instance was found in the given scope) then the body is ignored. To demonstrate:

<jsp:useBean  > If you see this we must have created a new bean! </jsp:useBean>

If no body is needed, the XML shorthand for an empty tag /> can be used:

<jsp:useBean   />

18.5.2 Controlling Bean Properties

The <jsp:setProperty> action provides the ability for request parameters to automatically (via introspection) set properties on the beans embedded within a page. This gives beans automatic access to the parameters of the request without having to call getParameter( ). This feature can be used in several ways. First:

<jsp:setProperty name="beanName" property="*" />

This says that any request parameter with the same name and type as a property on the given bean should be used to set that property on the bean. For example, if a bean has a setSize(int size) method and the request has a parameter size with a value of 12, the server will automatically call bean.setSize(12) at the beginning of the request handling. If the parameter value can't be converted to the proper type, the parameter is ignored. (Note that an empty string parameter value is treated as if the parameter does not exist and will not assign an empty string value to a String property.)

Notice that the action uses the XML shorthand for an empty tag. This is very important. The JSP specification requires all JSP actions to be well-formed XML, even when placed in HTML files. Here's the second <jsp:setProperty> usage:

<jsp:setProperty name="beanName" property="propertyName" />

This says that the given property should be set, if there's a request parameter with the same name and type. For example, to set the size property but no other property, use this action:

<jsp:setProperty name="prefs" property="size" />

Here's a third <jsp:setProperty> usage:

<jsp:setProperty name="beanName" property="propertyName" param="paramName" />

This says that the given property should be set, if there's a request parameter with the given name and the same type. This lets a parameter with one name set a property with another name. For example, to set the size property from the fontSize parameter:

<jsp:setProperty name="prefs" property="size" param="fontSize" />

This is the final usage:

<jsp:setProperty name="beanName" property="propertyName" value="constant" />

This says that the given property should be set to the given value, which will be converted to the appropriate type if necessary. For example, to set the default size to 18 with a parameter override:

<jsp:setProperty name="prefs" property="size" value="18" /> <jsp:setProperty name="prefs" property="size" param="fontSize" />

For advanced users, the value attribute does not need to be a constant; it can be specified using an expression with what's called a request-time attribute expression . For example, to ensure the size never drops below 6:

<jsp:setProperty name="prefs" property="size" param="fontSize" /> <jsp:setProperty name="prefs" property="size"      value="<%= Math.max(6, prefs.getSize()) %>" />

Finally, the <jsp:getProperty> action provides a mechanism for retrieving property values without using Java code in the page. Its usage looks much like that of <jsp:setProperty>:

<jsp:getProperty name="beanName" property="propertyName" />

This says to include at this location the value of the given property on the given bean. It's longer to type than an expression but eliminates the need to place Java code in the page. Whether to use <jsp:getProperty> or an expression is a matter of personal taste. Note that <jsp:getProperty> embeds the property value directly, so if it contains characters that HTML treats as special, that will cause problems. The Apache Struts project has a solution using a custom <property> tag, as we'll discuss later.

18.5.3 Saying "Hello" Using a Bean

Example 18-6 demonstrates the use of a JavaBeans component with a JSP page; it says "Hello" with the help of a HelloBean.

Example 18-6. Saying "Hello" Using a JavaBean
<%-- hello3.jsp --%> <%@ page import="HelloBean" %> <jsp:useBean  >   <jsp:setProperty name="hello" property="*" /> </jsp:useBean> <HTML> <HEAD><TITLE>Hello</TITLE></HEAD> <BODY> <H1> Hello, <jsp:getProperty name="hello" property="name" /> </H1> </BODY> </HTML>

As you can see, using a JavaBeans component with JavaServer Pages can reduce the amount of code placed into the page. The HelloBean class contains the business logic for determining a user's name, while the JSP page acts only as a template.

The code for HelloBean is shown in Example 18-7. Its class file should be placed in the standard directory for support classes (WEB-INF/classes).

Example 18-7. The HelloBean Class
public class HelloBean {   private String name = "World";   public void setName(String name) {     this.name = name;   }   public String getName() {     return name;   } }

This is about as simple a bean as you'll ever see. It has a single name property that is set using setName( ) and retrieved using getName( ). The default value of name is World, but when a request comes in that includes a name parameter, the property is set automatically by the server with a call to setName( ). To test the mechanism, try browsing to http://server:port/hello3.jsp. You should see something similar to the screen shot in Figure 18-4.

Figure 18-4. Saying "Hello" using JavaServer pages in cooperation with a JavaBeans component

One thing to watch out for: on some servers (including Tomcat 3.2) if you have a bean with a scope of session or application and you change the bean class implementation, you may get a ClassCastException on a later request. This exception occurs because the generated servlet code has to do a cast on the bean instance as it's retrieved from the session or application, and the old bean type stored in the session or application doesn't match the new bean type expected. The simplest solution is to restart the server.


Last updated on 3/20/2003
Java Servlet Programming, 2nd Edition, © 2001 O'Reilly

< BACKCONTINUE >


Java servlet programming
Java Servlet Programming (Java Series)
ISBN: 0596000405
EAN: 2147483647
Year: 2000
Pages: 223

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net