Chapter 9. JSP and JavaBeans

JSP is a presentation technology. Unlike a programming language such as Java, JSP does not have any built-in capability to access features offered by the underlying operating system or environment. JSP's capabilities are focused mainly around the generation of dynamic Web content.

JavaBeans are software components written in the Java programming language. JSP has built-in capabilities to work with JavaBeans. These capabilities are provided by the JSP standard actions and EL expressions. Because of this, JavaBeans have become the main mechanism for passing data and custom behavior between the JSP logic and the rest of the system in large Web applications.

In this chapter, this intimate relationship between JSP and JavaBeans is explored fully. The key topics covered in the chapter include the following:

  • Anatomy of a JavaBean

  • Packaging JavaBeans

  • JavaBean usage within JSPs

  • Accessing JavaBeans with standard actions

  • Accessing JavaBeans with EL

  • Accessing JavaBeans from scriptlets

  • Difference between a JavaBeans and an EJB

Two hands-on examples will clarify many of the concepts introduced. JavaBeans have already been used in the examples of previous chapters; most of the integration and application techniques are reviewed in this chapter.

Additional topics that are covered in the chapter include the following:

  • The use of a front-end JSP page (often called a front controller) to handle common tasks such as data validation. A front controller is a common design pattern for Web presentation layers. These and other common design patterns are discussed in Chapter 26, "Best Practices and Tools."

  • The typical flow of data, in a JSP Web application, using JavaBeans. The JavaBean used to collect and pass data across layers in your Web application is sometimes referred to as a transfer object or a data transfer object. This is another design pattern explained in more detail in Chapter 26.

By the end of this chapter, you will be familiar with JavaBeans as a software component, and their usage and application within JSPs. This will prepare you to work with the various JSP frameworks, where JavaBeans are used extensively to transport data between the business logic engine and the JSP-based presentation layer.

Anatomy of a JavaBean

A JavaBean is a specially constructed class written in the Java programming language. All JavaBeans are coded according to the JavaBeans API 1.0 Specifications for SUN (with a minor update to 1.01).

JavaBeans are reusable software components that can be wired together to create component-based applications. JavaBeans were originally designed for rapid application development environments. In these environments, visual JavaBeans can be dragged and dropped in the creation of user interfaces as well as application logic. All modern-day IDEs support the building of componentized applications using JavaBeans. The Swing API components are a good example of reusable JavaBean components.

Other than visual application design, JavaBeans are finding their way into many other uses, including the building of Web applications using JSP. In fact, even the earliest version of JSP had built-in standard actions that take advantage of JavaBeans.

The unique characteristics that distinguish a JavaBean from other Java classes include the following:

  • It must have a default constructor (i.e., no argument).

  • It may have a number of properties, the value of which can be read or written to.

  • It may have a number of methods that can be invoked.

  • Some JavaBeans are visual (i.e., AWT or Swing-based) and can be placed into an IDE during the design of a user interface.

  • It is designed to be a self-contained component, used in assembling a components-based application.

Note

Every JavaBean should also be serializable (and implement the Serializable interface). This is necessary because the state of visual JavaBeans may be serialized by its container (i.e., an IDE during development, or a framework during runtime). However, many nonvisual JavaBeans (and even some visual JavaBeans) do not conform to this requirement.

Figure 9-1 illustrates these interesting characteristics of a JavaBean.

Characteristics of JavaBeans

Figure 9.1. Characteristics of JavaBeans

Of the aforementioned unique characteristics of JavaBeans, the first three (constructor, properties, and methods) are the most important to JSP developers. The next two characteristics (events and visual design interface) are gaining relevance as sophisticated frameworks based on JavaBeans, such as JavaServer Faces (JSF), become available. JSF is covered in Chapter 21, "JavaServer Faces." The final characteristic is also important architecturally—a JavaBean adds incremental and reusable functionality to applications built using JSP, and thus enable the application to be built based on the assembly of software components.

JavaBean Properties

A JavaBean property is a named attribute that can be accessed by the user of the component. The attribute can be of any Java data type, including classes that you define. For example, the firstName property of a Customer JavaBean (for an auction Web site, for example) may be of type String, while the lastOrder property of the same JavaBean may be of a custom Java type called Order. Figure 9-2 shows such a Customer JavaBean with its properties.

The property of a JavaBean may be read/write, read only, or write only.

A read/write property is accessed through two methods in the JavaBean's implementation class:

  • get<PropertyName>() method

  • set<PropertyName>() method

Customer JavaBean properties

Figure 9.2. Customer JavaBean properties

For example, if the firstName property of the Customer JavaBean is read/write, then the firstName property can be accessed in one of the two following ways:

  • getFirstName() method to obtain its value

  • setFirstName() method to set its value

A read-only attribute will have only a get<PropertyName>() method, and a write-only attribute will have only a set<PropertyName>() method.

Note

There is an exception to this rule: By JavaBean convention, a property of boolean primitive type is not obtained by a get<PropertyName>() method. The read access is implemented by a is<PropertyName>() method instead. For example, if the property called goldMember exists on the customer, then the boolean property can be tested with Customer.isGoldMember().

Coding JavaBean properties

The Customer JavaBean mentioned previously may have the following Java coding:

public class Customer
{
    private String firstName = null;
    private String lastName = null;
    private Order lastOrder = null;
private boolean goldMember = false;

    public Customer()
    {
    }

    public long getFirstName()
    {
        return this.firstName;
    }


    public void setFirstName(String inName)
    {
        this.firstName = inName;
    }

    public long getLastName()
    {
        return this.lastName;
    }


    public void setLastName(String inName)
    {
        this.lastName = inName;
    }


    public Order getLastOrder()
    {
        return this.lastOrder;
    }

    public void setLastOrder(Order inOrder)
    {
        this.lastOrder = inOrder;
    }


    public boolean isGoldMember()
    {
        return this.goldMember;
    }

    public void setGoldMember(boolean inGoldMember)
    {
        this.goldMember = inGoldMember;
    }
}

In the preceding code for the Customer JavaBean, all of the firstName, lastName, goldMember, and lastOrder properties have read/write access. As a result, there is a get<PropertyName> () method, and a set<PropertyName>() method associated with each property. For example, the firstName property has getFirstName() for reading and setFirstName() for writing. The only exception is the goldMember property. goldMember is a boolean typed property and its getter method is called isGoldMember() instead of getGoldMember().

JavaBean methods

A method exported by a JavaBean is simply a public method within the Java class. For example, a Shop JavaBean may export a method called CalculateShipping. It may be coded as follows:

public class Shop
{
 .....
    public long CalculateShipping(String sourceZIP, String destinationZIP, long
shipBy)
    {
...
    }
 .....
}

Invoking JavaBean methods using scriptlets

Methods of JavaBeans may be invoked within a JSP page using scriptlets. Scriplets enable you to embed Java code within a JSP page. Chapter 3, "JSP Basics 2: Generalized Templating and Server Scripting," covers the use of scriptlets. For example, to invoke the preceding method on a JavaBean instance called MyShop, the following scriplet code may be used:

<%
  long shippingCharges = MyShop.CalculateShipping("32231", "32718", ShipBy.UPS);
%>

This code assumes that the result is stored in a Java variable called shippingCharges, to be used later in the JSP. It also assumes that the ShipBy.UPS constant is a long value that the CalculateShipping() method understands.

Scriptless JSP and EL functions

Scriplets and scripting elements are presented in Chapter 3. The main purpose of that coverage is to ensure that you will be able to maintain legacy code that contains embedded Java coding. Chapter 3 is explicit in its recommendation to not use scripting elements for any new JSP code if possible. The creation of scriptless JSP code leads to code that is easier to maintain in the long term.

Without scriplets, there is no direct way for a JSP to invoke methods of a JavaBean. This is a good feature if you consider the role of JSP within a Web application. JSP should be used for presentation only. This means that it should not be allowed to access any random method in an arbitrary Java class. Allowing such behavior can encourage the bundling of application logic within JSP coding. Bundling application logic with the JSP presentation layer leads to code that is hard to maintain, and applications that cannot scale to a large number of users.

Note

While scriptless JSP cannot invoke a JavaBean method directly, useful functions such as the CalculateShipping() shown earlier can be wrapped up as an EL function. EL functions are a feature of EL that enables you to extend its capability via the definition of pubic static functions in a Java class. See Chapter 5, "JSP and EL," for more information on EL and how to create EL functions.

Common JavaBean packaging

JavaBeans are compiled into Java classes and just like the other Java classes in your application, they can be packaged into a JAR file and placed into the WEB-INF/lib directory of your application.

During development, however, it is usually more convenient to place the individual class files, unarchived, under the WEB-INF/classes directory. If you are using an IDE, you can conveniently do this by setting your compilation target directory to the WEB-INF/classes directory. Doing this helps provide a faster modify-recompile cycle during development.

The following Try It Out example illustrates a technique for performing form input validation. It demonstrates one of the most typical uses of JavaBeans in JSPs: to carry data between pages (or between business logic and the presentation layer). This example presents the user interface of a very simple auction.

How It Works

During the experimentation in the previous section, you may have noticed one unusual browser behavior. Unlike the examples in previous chapters, all the screens in this example have the same URL:

http://localhost:8080/ch09/example1/index.jsp

If you look back at Figure 9-3, Figure 9-4, and Figure 9-5, you will notice that they all appear to be using the preceding URL, yet the screens being rendered and the functions being performed are definitely different.

Switching requests through a front controller

Indeed, every single request of this Try It Out application is first sent to the index.jsp page. The index.jsp page is then responsible for the following:

  • Performing some common tasks such as input form data validation

  • Redirecting the request to the appropriate JSP page

Figure 9-6 reveals this application's architecture.

Front controller architecture

Figure 9.6. Front controller architecture

In Figure 9-6, index.jsp forwards the requests to one of two different JSP pages:

  • enterbid.jsp

  • showbid.jsp

In production, index.jsp may actually forward requests to many different JSPs depending on application requirements. The major benefits delivered by this architecture include the following:

  • Application URL hiding: The user sees only the index.jsp URL.

  • Factoring of reusable code/logic: index.jsp does form data validation that may be required by many different forms within the application.

  • Elimination of hard-wired relationships between JSP pages: This makes the application easier to maintain; the actual flow between pages in the application is determined by index.jsp, and not hard-coded in URL links within the JSP pages themselves.

In this capacity, the index.jsp page acts as controller (or front controller). It is easy to see how both the appearance and interactions of the entire application are controlled through the logic in index.jsp.

The key enabling technical component for the operation of this architecture is the JavaBean. Without the use of JavaBeans, designing JSP applications using this architecture would not be possible. To see why, consider Figure 9-7.

JavaBeans and the front controller

Figure 9.7. JavaBeans and the front controller

In Figure 9-7, the front controller (index.jsp) is viewed as a switch for the incoming requests. This is another common way to view the architecture. The incoming requests are processed by the front controller and then switched to one of the presentation processors (JSP) to display the output of the processed request. The only data element that is passed between the front controller and a JSP is the incoming request itself. To pass information between the front controller and the presentation JSPs, JavaBeans are attached as named attributes (attached data in Figure 9-7) to the request. The JavaBeans enable arbitrarily complex data elements to be passed between the front controller and the presentation JSPs—this is the vital role of JavaBeans in the architecture.

You will see this use of JavaBeans again and again in your daily JSP development. Almost all modern Web application frameworks deploy JavaBeans in this fashion.

The index.jsp front controller

Let's now examine the code that implements this. The index.jsp front controller can be located at <Tomcat Installation Directory>/webapps/ch09/example1/index.jsp. The entire index.jsp code is reproduced here:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:choose>
  <c:when test="${empty param.action}">
    <jsp:forward page="enterbid.jsp"/>
  </c:when>
  <c:when test="${param.action eq 'bid'}">
    <c:if test="${(param.price <= 0) ||  (param.price >= 999)}">
      <jsp:useBean id="biderror" class="com.wrox.begjsp.ch09.BidError"
scope="request">
<jsp:setProperty name="biderror" property="msg" value="Sorry, your bid is
not in range. Please enter again."/>
      </jsp:useBean>
      <jsp:forward page="enterbid.jsp"/>
    </c:if>

    <jsp:useBean id="bidinfo" class="com.wrox.begjsp.ch09.Bid" scope="request">
      <jsp:setProperty name="bidinfo" property="*"/>
    </jsp:useBean>

    <jsp:forward page="showbid.jsp"/>
  </c:when>
</c:choose>

You can see that index.jsp consists of one JSTL <c:choose> construct. This construct is used to switch the incoming request to different presentation JSPs. In this case, it will be either enterbid.jsp or showbid.jsp. The incoming request parameter that the switching is dependent on is called action. The following code shows the <c:choose> construct used to switch the request based on the value of the action parameter:

<c:choose>
  <c:when test="${empty param.action}">
...
  </c:when>
  <c:when test="${param.action eq 'bid'}">
     ....
  </c:when>
</c:choose>

Initially, when the index.jsp page is called up, there will be no action parameter. In this case, the code in the first <c:when> tag is executed. When the bid form is submitted, the value of the action parameter will be set to 'bid', and the code in the second <c:when> will be executed. For any specific incoming request, only one of the <c:when> tags will be executed.

Note

The role of the action parameter in this architecture is called the forward. The front controller switches requests to different targets (JSP pages) depending on the forward (different value of the action parameter).

Forwarding to different targets

The code in the first <c:when> is quite straightforward. This code is executed when the index.jsp URL is first accessed:

<c:when test="${empty param.action}">
    <jsp:forward page="enterbid.jsp"/>
  </c:when>

The EL empty operator is used determine that the action parameter is null (i.e., has not been defined). The action performed here is a forward of the request to the enterbid.jsp form for input of bid data.

The code in the second <c:when> is also quite straightforward. This code is executed when the enterbid.jsp form is submitted to the front controller (index.jsp). Within enterbid.jsp, a hidden parameter with the name action is set to the value of 'bid'. This signals index.jsp to perform data validation and then forward the request accordingly. Figure 9-8 shows the action performed by the code in this second <c:when> construct.

Front controller forwarding requests depending on the action parameter

Figure 9.8. Front controller forwarding requests depending on the action parameter

In Figure 9-8, the request is forwarded to one of two targets:

  • Back to enterbid.jsp if the bid is out of range (input data validation fails)

  • To showbid.jsp if the bid is in the valid range (greater than 0 and less than 999)

JavaBean flow for validation error reporting

The code for this second <c:when> construct is as follows:

<c:when test="${param.action eq 'bid'}">
    <c:if test="${(param.price <= 0) ||  (param.price >= 999)}">
      <jsp:useBean id="biderror" class="com.wrox.begjsp.ch09.BidError"
scope="request">
<jsp:setProperty name="biderror" property="msg"
value="Sorry, your bid is not in range. Please enter again."/>
      </jsp:useBean>
      <jsp:forward page="enterbid.jsp"/>
    </c:if>

    <jsp:useBean id="bidinfo" class="com.wrox.begjsp.ch09.Bid" scope="request">
      <jsp:setProperty name="bidinfo" property="*"/>
    </jsp:useBean>

    <jsp:forward page="showbid.jsp"/>
</c:when>

First, an EL expression is used to determine that the action parameter has the value bid:

<c:when test="${param.action eq 'bid'}">

Next, the incoming request parameter called price is validated to be within the allowed range:

<c:if test="${(param.price <= 0) ||  (param.price >= 999)}">
...
</c:if>

Accessing JavaBeans using standard actions

The code in this <c:if> tag will be executed only if the price is out of range. It is in this code that an error message JavaBean is created and sent back to the enterbid.jsp to be displayed to the user. The code in the <c:if> tag is reproduced here:

<jsp:useBean id="biderror" class="com.wrox.begjsp.ch09.BidError" scope="request">
    <jsp:setProperty name="biderror" property="msg"
value="Sorry, your bid is not in range. Please enter again."/>
  </jsp:useBean>
  <jsp:forward page="enterbid.jsp"/>

The <jsp:useBean> standard action is used to create an instance of the BidError JavaBean and attach it to the request scope. If you need a review of the <jsp:useBean> tag and how it creates new instances of JavaBeans, see Chapter 8, "JSP Standard Actions." This newly created instance of the JavaBean is attached to the request implicit object as an attribute named biderror. Because the request is passed during a <jsp:forward>, it will be available within the target enterbid.jsp.

Within the <jsp:useBean> tag, the msg property of the JavaBean is set to the required error message using the <jsp:setProperty> standard action. In this case, the error message is as follows:

Sorry, your bid is not in range. Please enter again.

The code within the <jsp:useBean> standard action will execute only if the named JavaBean is created successfully.

The validation error information JavaBean

The BidError JavaBean is created to carry error information between the front controller's form validation logic and the presentation JSPs. You can find the code at <Tomcat Installation Directory>/webapps/ch09/example1/WEB-INF/classes/com/wrox/begjsp/ch09/BidError.java. The source code of the BidError.java JavaBean is reproduced here:

package com.wrox.begjsp.ch09;
public class BidError
{
    private String msg;
    public BidError()
    {
    }
    public String getMsg()
    {
        return this.msg;
    }


    public void setMsg(String msg)
    {
        this.msg = msg;
    }
}

This BidError JavaBean has only a single read/write property called msg. The getMsg() method is implemented for the reading of this property, and the setMsg() method is implemented for writing this property. Internally, the value of the property is kept in a String typed private field also called msg.

The enterbid.jsp target

The form that takes bids from the user is enterbid.jsp. It is located at <Tomcat Installation Directory>/webapps/ch09/example1/enterbid.jsp. The content of enterbid.jsp is reproduced here:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
  <link rel=stylesheet type="text/css" href="auction.css">
  <title>Enter Your Bid</title></head>
<body>
  <table class="mainBox" width="400">
    <tr><td class="boxTitle" colspan="2">
      Wrox JSP Auction
    </td></tr>
    <c:if test="${!(empty biderror)}">
    <tr>
      <td class="errorText" colspan="2">
         ${biderror.msg}
      </td>
    </tr>
    </c:if>
<tr><td colspan="2">&nbsp;</td></tr>
    <tr><td>
      <form  action="index.jsp" method="get">
        <table>
          <tr>
            <td width="200">Item to bid on</td><td>
              <select name="item">
                <option>27 inch TV</option>
                <option>DVD Player</option>
                <option>Digital Camera</option>
              </select>
              <input type="hidden" name="action" value="bid"/>
            </td>
          </tr>
          <tr>
            <td>Bid Price:</td>
            <td><input name="price" type="text" width="10"/>
            </td>
          </tr>
          <tr><td colspan="2">&nbsp;</td></tr>
          <tr><td colspan="2" align="center">
            <input type="submit" value="Bid now!"/>
          </td></tr>
        </table>
      </form>
    </td></tr>
  </table>
</body>
</html>

It is an HTML form with a <select> form element and a text typed <input> form element. The highlighted portion in the preceding code checks for and prints any validation error message if it exists. The biderror JavaBean from index.jsp, transported as an attribute attached to the request, is used to determine whether a validation has occurred. This JavaBean is accessed through the EL in this case.

Accessing JavaBeans through EL

The validation error message rendering code in the enterbid.jsp uses EL to access the biderror JavaBean. It adds an additional row to the table if an error occurred:

<c:if test="${!(empty biderror)}">
  <tr>
    <td class="errorText" colspan="2">
      ${biderror.msg}
    </td>
  </tr>
</c:if>

First, the empty EL operator determines whether the biderror attribute is available. The biderror attribute will not exist if enterbid.jsp is accessed for the first time because index.jsp forwards to the page without creating any JavaBean. Only if the biderror attribute is found will the extra row in the table be rendered. Note the very simple access to the msg property value of the biderror JavaBean using EL:

${biderror.msg}

Using EL to render a JavaBean property value is simple and concise.

Displaying bid information via a JavaBean

If the bid price entered by the user is within the allowable range, the front controller index.jsp will forward the request to the showbid.jsp target. The code to do this is in the second <c:when> tag within index.jsp, after the <c:if> check for bid price validity:

<jsp:useBean id="bidinfo" class="com.wrox.begjsp.ch09.Bid" scope="request">
       <jsp:setProperty name="bidinfo" property="*"/>
     </jsp:useBean>
     <jsp:forward page="showbid.jsp"/>

The preceding code creates a new Bid JavaBean instance and calls it bidinfo, using the <jsp:useBean> tag. Note that the special "*" value is used to assign the incoming input form data value to the properties of the bean.

Filling JavaBean properties with incoming request parameters

When the special "*" value for the property attribute is included in a standard <jsp:setProperty> action, the JSP runtime will match the name of the request parameter against the name of the properties of the JavaBean referenced. (For a discussion of this special value, see Chapter 8.) In this case, the JavaBean is called bidinfo and is an instance of the Bid JavaBean. This JavaBean has two properties:

  • item

  • price

This matches the incoming form parameters, filled out using enterbid.jsp, exactly. This will result in the assignment of the item parameter to the item property of bidinfo, and the assignment of the price parameter to the price property of bidinfo. Because the <jsp:useBean> created the bidinfo attribute in the request scope, the bidinfo JavaBean instance will travel with the forwarded request to showbid.jsp.

The Bid JavaBean

The code for the Bid JavaBean can be found at <Tomcat Installation Directory>/webapps/ch09/WEB-INF/classes/com/wrox/begjsp/ch09/Bid.java. The Bid.java code is reproduced here:

package com.wrox.begjsp.ch09;
public class Bid
{
    private long price;
    private String item;

    public Bid()
    {
    }

    public long getPrice()
{
        return this.price;
    }

    public void setPrice(long price)
    {
        this.price = price;
    }

    public String getItem()
    {
        return this.item;
    }

    public void setItem(String item)
    {
        this.item = item;
    }
}

This JavaBean has two properties: price and item. They are both read/write properties. A get<PropertyName> () and a set<PropertyName>() method are created for each property.

The showbid.jsp target

Back in index.jsp, after creating the Bid JavaBean instance and setting its property values, the request is forwarded to the showbid.jsp target via a <jsp:forward> standard action:

<jsp:useBean id="bidinfo" class="com.wrox.begjsp.ch09.Bid" scope="request">
       <jsp:setProperty name="bidinfo" property="*"/>
     </jsp:useBean>
     <jsp:forward page="showbid.jsp"/>

The code for showbid.jsp can be located at <Tomcat Installation Directory>/webapps/ch09/example1/showbid.jsp. The content of showbid.jsp is presented here:

<html>
<head>
  <link rel=stylesheet type="text/css" href="auction.css">
  <title>Show the Bid</title>
</head>
<body>
  <table class="mainBox" width="600">
    <tr><td class="boxTitle" colspan="2">
      Your Auction Bid
    </td></tr>
    <tr><td colspan="2">&nbsp;</td></tr>
    <tr>
      <td class="tableLabel" width="30%">
        Item bid for
      </td>
<td class="tableCell">
        ${bidinfo.item}
      </td>
    </tr>
    <tr>
      <td class="tableLabel">
        Bid price
      </td>
      <td class="tableCell">
        ${bidinfo.price}
      </td>
    </tr>
  </table>
</body>
</html>

This JSP page renders the property values of the bidinfo JavaBean instance using EL. The two lines rendering the values are highlighted in the preceding code.

Formatting auction output pages with a CSS stylesheet

Both enterbid.jsp and showbid.jsp use a CSS stylesheet to format the HTML output. The stylesheet is called auction.css and can be located at <Tomcat Installation Directory>/webapps/ch09/example1/auction.css.

The content of this stylesheet is shown here:

.tableCell
{
  font-family : Verdana, Geneva, Arial, Helvetica, sans-serif;
  font-size : 16;
  font-weight : bold;
  color : #0f7fcf;
  background-color: #ffffff;
}

.resultCell
{
  font-family : Verdana, Geneva, Arial, Helvetica, sans-serif;
  font-size : 16;
  font-style: italic;
  font-weight : bold;
  color : #000000;
  background-color: #ffffff;
}

.tableLabel
{
font-family : Verdana, Geneva, Arial, Helvetica, sans-serif;
  font-size : 18;
  color : #000000;
  background-color: #ffffff;
}

.errorText
{
  font-family : Verdana, Geneva, Arial, Helvetica, sans-serif;
  font-size : 16;
  font-weight : bold;
  color : #ffffff;
  background-color: #ff0000;
}

.boxTitle
{
  font-family : Arial, Helvetica, sans-serif;
  font-size : 22;
  font-weight : bold;
  color : #ffffff;
  background-color: #0F7ACA;

}
.mainBox
{
  font-family : Verdana, Geneva, Arial, Helvetica, sans-serif;
  font-size : 12;
  color : #ffffff;
  background-color: #eeeeee;
}

This completes the coverage of the first example. The next Try It Out exercise is built on the first, and shows how you can use JavaBeans to carry information from custom application logic to the JSP pages.

How It Works

This example consists of the same three JSP pages as the first example:

  • index.jsp

  • enterbid.jsp

  • showbid.jsp

Bid result displayed by the new showbid.jsp

Figure 9.10. Bid result displayed by the new showbid.jsp

Only enterbid.jsp and showbid.jsp have been modified. The example also makes use of the JavaBeans shown in the following table.

JavaBean

Usage Description

Bid

Used to carry bid information from the front controller index.jsp to the showbid.jsp presentation page

BidError

Used to carry error information from the front controller index.jsp to the enterbid.jsp when a validation error occurs

Bidder

Used to simulate the action of bidding

The Bidder JavaBean

The new Bidder JavaBean is located at <Tomcat Installation Directory>/webapps/ch09/WEB-INF/classes/com/wrox/begjsp/ch09/Bidder.java.

The code is reproduced here:

package com.wrox.begjsp.ch09;

public class Bidder
{

    private String item;
    private long price;
    private String result;

    public Bidder()
    {
    }

    public String getItem()
    {
        return this.item;
    }

    public void setItem(String item)
    {
        this.item = item;
    }

    public long getPrice()
    {
        return this.price;
    }

    public void setPrice(long price)
    {
        this.price = price;
    }

    public String getResult()
    {
        /* simulate bid result */
        this.result = "Sorry your bid did not win. The successful bidder was joe1233.";
        return this.result;
    }
}

This Bidder JavaBean simulates the bidding action. You need to do the following:

  • Set the value of the item and price properties.

  • Read the value of the result property.

The result property value contains a string that indicates the result of the bid.

In production, this method can access a back-end network to determine the actual result of the bid.

Modifying the controller to fetch bidding results

The index.jsp front controller page is modified to fetch the bidding result in an instance of the Bidder JavaBean before forwarding the request to the showbid.jsp page.

You can find the modified index.jsp at <Tomcat Installation Directory>/webapps/ch09/example2/index.jsp. The code of this modified page is presented here, with the modifications highlighted:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:choose>
  <c:when test="${empty param.action}">
    <jsp:forward page="enterbid.jsp"/>
  </c:when>
  <c:when test="${param.action eq 'bid'}">
    <!--  validation code -->
    <c:if test="${(param.price <= 0) ||  (param.price >= 999)}">
      <jsp:useBean id="biderror" class="com.wrox.begjsp.ch09.BidError" scope="request">
        <jsp:setProperty name="biderror" property="msg" value="Sorry, your bid is not in range. Please enter again."/>
      </jsp:useBean>
      <jsp:forward page="enterbid.jsp"/>
    </c:if>
    <!-- data validated -->
    <jsp:useBean id="bidinfo" class="com.wrox.begjsp.ch09.Bid" scope="request">
      <jsp:setProperty name="bidinfo" property="*"/>
    </jsp:useBean>

    <!-- perform bidding -->
    <jsp:useBean id="bidder" class="com.wrox.begjsp.ch09.Bidder" scope="request">
      <jsp:setProperty name="bidder" property="item"/>
      <jsp:setProperty name="bidder" property="price"/>
    </jsp:useBean>
    <c:set var="bidresult" value="${bidder.result}" scope="request"/>
    <jsp:forward page="showbid.jsp"/>
  </c:when>
</c:choose>

The <jsp:useBean> standard action is used here to create an instance of the Bidder JavaBean, attaching it as a request scoped attribute called bidder. The <jsp:setProperty> standard action is used to set the item and price property of the bidder JavaBean instance. Note that this could also have been done using the single <jsp:setProperty> action and the special "*" value:

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

Using JSTL to access a JavaBean

The last lines highlighted in the new index.jsp controller are as follows:

<c:set var="bidresult" value="${bidder.result}" scope="request"/>
     <jsp:forward page="showbid.jsp"/>

Here, the JSTL <c:set> custom action is used to retrieve a JavaBean's property value. The value obtained is the value of the result property; it is of type String. This value is then attached to the request scope as a scoped variable called bidresult. This technique can be used to access an attribute of a JavaBean regardless of its data type. The resulting bidresult request scope variable will be available within the showbid.jsp target, together with the bidinfo JavaBean instance.

Note

One of the main purposes of a front controller in a system is to manage communications with back-end application logic. This communication can result in multiple JavaBeans attached to the requests, forwarded to the presentation JSP for rendering. In the preceding Try It Out exercise, this is exemplified by the data carrying both bidinfo and bidresult JavaBeans.

Presenting bid results in showbid.jsp

One other element changed from the showbid.jsp page of the last Try It Out exercise. This page has been modified to show the bid results. The new showbid.jsp is located at <Tomcat Installation Directory>/webapps/ch09/example2/showbid.jsp. The page is shown here, with modifications highlighted:

<html>
<head>
  <link rel=stylesheet type="text/css" href="auction.css">
  <title>Show the Bid</title></head>
<body>
  <table class="mainBox" width="600">
    <tr><td class="boxTitle" colspan="2">
      Your Auction Bid
    </td></tr>
    <tr><td colspan="2">&nbsp;</td></tr>
    <tr><td class="tableLabel" width="30%">
        Item bid for
      </td>
      <td class="tableCell">
        ${bidinfo.item}</td>
    </tr>
    <tr>
      <td class="tableLabel">
        Bid price
      </td>
      <td class="tableCell">
        ${bidinfo.price}
      </td>
    </tr>
    <tr>
      <td class="tableLabel">
        Bid result
      </td>
      <td class="resultCell">
        ${bidresult}
      </td>
    </tr>

  </table>
</body>
</html>

Because the bidresult attribute is already of String data type, it is simply rendered within a new table row using the EL expression:

${bidresult}

This concludes the coverage of using JavaBeans to carry information between custom application logic and the JSP presentation layer.

How JavaBeans and EJBs Differ

The JavaBeans covered in this chapter are Java classes coded according to the JavaBeans API specification. They are reusable software components that expose properties, methods, and events for external access. The JSP usage of these JavaBeans is focused around the transfer of data between different JSP pages. In this chapter, JavaBeans are used to transfer data between a single front controller and many different presentation JSPs.

JSP is a technology residing exclusively in the presentation layer (of the Web tier) within the J2EE (Java 2 Enterprise Edition) architecture. J2EE is a large specification that encompasses many aspects of enterprise application building using Java as the programming language.

Enterprise JavaBeans, or EJBs for short, reside within the business logic tier of an enterprise system. This tier is completely separate and independent from the Web tier in which the JSP resides. In fact, it is entirely possible to create JSP-based applications without the use of EJB.

Unlike the JavaBeans presented here, EJBs execute within their own highly specialized container. The container will have access to an enterprise's database, communications, and security resources.

The J2EE architecture is covered in Chapter 22, "JSP in J2EE," and you will learn a little about EJB in that chapter. A thorough coverage of J2EE and/or EJB is beyond the scope of this book. The important thing to realize at this point is that the JavaBeans used in this chapter are not EJBs, and that EJBs are not essential to creating applications using JSPs. In fact, even within enterprise Java applications, JSP as a presentation technology seldom has access to EJBs. Instead, EJBs are usually accessed via code written in the Java programming language called a servlet. Servlets are covered in Chapter 15, "JSP and Servlets."

Summary

JavaBeans are software components created using the Java programming language that expose properties, methods, and events. JavaBeans...

  • Play a vital role in the creation of applications using JSP.

  • Are used to transfer complex data with the incoming request.

  • Can be used in JSP via the built-in standard actions <jsp:useBean>, <jsp:setProperty>, and <jsp:getProperty>.

  • Can be accessed using raw Java language code in the form of embedded scriplets scripting elements. This practice is now discouraged, although you might come across such JSPs while maintaining legacy code.

  • Can be packaged into JAR files and placed into the application's lib directory.

  • Can be placed under the WEB-INF/classes directory for a faster modify-recompile cycle during development.

  • Can be manipulated readily using JSTL/EL, especially when used as scoped variables. The JSTL <c:set> tag can be used to attach a JavaBean-based attribute to the request implicit object. EL expressions can be used to render JavaBean property values.

JavaBeans are not the same as, and should not be confused with, Enterprise JavaBeans (EJBs). EJBs run in their own special container, and are in a different architectural tier than JSPs.

The chapter also explored the front controller design pattern. Having a front controller in a JSP application, you learned the following:

  • By using a front controller to forward incoming requests to different JSPs, you can isolate common functions such as form data validation in one place.

  • Using such a front controller enables you to write JSP applications in which the pages are not hard-wired to one another, leading to better maintainability.

Exercises

  1. Modify the first Try It Out exercise to do the following:

    1. Remember the selected bid item when the enterbid.jsp is re-displayed during a validation error

    2. Remember the bid price entered when the enterbid.jsp is re-displayed

    3. Highlight the bid price label in red, emphasizing that the value is invalid

  2. Modify the second Try It Out exercise to

    1. Include a new winner.jsp page

    2. Remove the upper bid limit of $999

    3. Forward to this new winner.jsp page if the incoming bid price is over $1,000

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.128.29.47