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.
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.
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.
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.
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
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.
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()
.
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()
.
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) { ... } ..... }
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.
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.
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.
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.
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.
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.
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.
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.
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.
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).
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.
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)
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>
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 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 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"> </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"> </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.
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"> </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.
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.
This example consists of the same three JSP pages as the first example:
index.jsp
enterbid.jsp
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 |
---|---|
| Used to carry bid information from the front controller |
| Used to carry error information from the front controller |
| Used to simulate the action of bidding |
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.
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.
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"> </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.
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."
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.
Modify the first Try It Out exercise to do the following:
Remember the selected bid item when the enterbid.jsp
is re-displayed during a validation error
Remember the bid price entered when the enterbid.jsp
is re-displayed
Highlight the bid price label in red, emphasizing that the value is invalid
Modify the second Try It Out exercise to
Include a new winner.jsp
page
Remove the upper bid limit of $999
Forward to this new winner.jsp
page if the incoming bid price is over $1,000
3.128.29.47