|
Simplify JSP Applications with JavaBeans, Part 2
by Richard Shaler
[The code for this article is available for
download.]
In my last
article, I illustrated how to simplify a JSP application by pulling some logic out of the JSP and placing
it in a JavaBean. In this article I'll illustrate how you can make the JavaBean more reusable than it was in
the previous article. The JavaBean will become truly independent of any other component of the
application. The modified JavaBean will be much easier to plug into essentially any application that may
need it.
In part 1 of this series, I started with a very simple application (version 1) containing only two components:
an HTML input form and a JSP that performed the processing and output for the application. That
application was very easy to create, but it had the weakness of containing the business logic and
presentation logic in a single monolithic JSP. That application's components are illustrated here:
Mixing too much presentation logic and business logic into one component can make it difficult to perform
maintenance. A better approach would be to keep presentation logic separate from business logic. The Web
designer could then work with a separate component containing mostly presentation logic, and the business
programmer could work on a different component containing mostly business logic.
I modified that application to separate presentation from business logic by pulling some of the processing
out of the JSP and placing it in a servlet and a JavaBean. The servlet acted as the controller for the
application, and the JavaBean contained the business logic. The modified version (version 2) is illustrated
here:
In this article, I modify version 2 of the application to create a version 3 of the original sample application.
As always, it will be helpful for you to have the source code of the sample application available for your
examination as you read this material. The code for this article is available for download. Be sure to read
my previous article, "Simplify JSP Applications with JavaBeans, Part 1."
Weaknesses in Version 2 JavaBean
In version 2, I did accomplish some separation of business logic from presentation logic, but I didn't go as
far as I could have. If you look at the components in the previous illustration, you can see that the
connection to the database is performed in the servlet. The JavaBean uses this connection object to retrieve
the information from the database. One weakness in this design is that the JavaBean depends on the
connection from the servlet. Another weakness is that I overloaded the constructor of the JavaBean to pass
the connection object and the customer number to the JavaBean. This creates a need to understand the
signature (the parameter list and parameter types) of a constructor method before the JavaBean can be
instantiated and exploited. Creating a constructor with a parameter list goes against one of the basic
guidelines of JavaBeans: The constructor should have an empty parameter list. I take care of these
weaknesses in the sample application (version 3) presented here.
Sample Application, Version 3
To help you understand the application from a user's perspective, I've included two browser page captures
to illustrate the application flow. This is the input form:
The input form allows the user to key in a customer number for which they would like to display the
customer last name. The form also allows the user to choose a JDBC driver via two radio buttons: DB2 for
iSeries or DB2 for Windows. I added this feature to help illustrate how you can build runtime flexibility
into a JavaBean.
The output of the application is illustrated here:
The customer's last name is displayed alongside the customer number that was submitted. Also notice the
driver chosen by the user is displayed in the header area of the form.
Version 3 Improvements
In version 3 of the sample application I make two changes. First, I pull the connection code out of the
servlet and placed it in the JavaBean by replacing the overloaded constructor method with a new "setter"
method setCustLastName. Second, I enhance the application by allowing the user to choose between two
JDBC drivers: a DB2 for iSeries driver or a DB2 for Windows driver. The following illustration shows how
the application components are used in version 3:

Notice that the "Better" JavaBean now contains the connection code, the retrieval code, and the "getter" and
"setter" methods. Moving the connection code into the JavaBean eliminates the need to pass the connection
object to the JavaBean. (In version 2, the connection was made in the servlet, which then had to be passed
to the JavaBean.) Now, this is not to say that having the connection code in the servlet was all bad. One of
the advantages of making the connection in the servlet was that it was done only once (in the servlet's
special init method). The connection code in the JavaBean, on the other hand, will be executed everytime
the customer's last name is request from the bean. This is not good for performance. However, for a
production application, you would use connection pooling (or even DataAccessObject pooling), which
would allow your JavaBean to access an open JDBC connection from a pool and thereby eliminate the
performance issue.
Remove Dependency Between Servlet and JavaBean
Moving the connection code from the servlet to the JavaBean was trivial, since the actual Java code that
performs the connection will execute in the JavaBean. I created a setter method (setCustLastName), which
takes one parameter, the customer number. I embedded the connection code, the customer retrieval code
(the SQL statement), and set the custLastName property to the LSTNAM column of the QCUSTCDT table.
I've included the setCustLastName method definition, minus the working code, below with comments
about the three major functions it performs.
public void setCustLastName (BigDecimal nbr) {
// get connection
// get customer via SQL select statement
// set the custLastName property to the LSTNAM column value
}
(See the source member CustomerLastNameBean.java for the complete code.)
The custLastName property is set in the servlet (the controller of the application) through the
setCustLastName method of the JavaBean after the CustomerLastNameBean JavaBean is instantiated and
the JDBC driver is set.
CustomerLastNameBean cust = new CustomerLastNameBean();
cust.setDriver(driver);
cust.setCustLastName(nbr);
Once the custLastName property is set, any component of the application can retrieve its value through the
getCustLastName method. Here, the JSP retrieves the value through a JSP expression statement.
<%= CustomerLastNameBean.getCustLastName()%>
Provide JDBC Driver Choice
The main reason I added the JDBC driver choice to the application was to illustrate how easy it is to add
runtime flexibility to a JavaBean. This is accomplished by the servlet
(CustomerLastNameControllerServlet) retrieving the driver choice made by the user, from the HTML input
form, and passing it to the setDriver method of the JavaBean (CustomerLastNameBean). Based on the
driver value, the CustomerLastNameBean loads the appropriate JDBC properties file. Property files are a
very useful way to add flexibility to your Java applications. You basically store key/value pairs in a simple
text file, which can be easily retrieved by any Java class. If you want to change the properties your
application uses, you simply change the properties file contents--you have no need to recompile and deploy
Java components. Here is the conditional code used by the JavaBean to get the appropriate JDBC
properties.
try {
if (driver.equals("iseries"))
input = new FileInputStream("c:/Apache Tomcat 4.0/webapps/custlastname/WEB-
INF/jdbc400.properties");
else
if (driver.equals("windows"))
input = new FileInputStream("c:/Apache Tomcat 4.0/webapps/custlastname/WEB-
INF/jdbcwin.properties");
} catch (FileNotFoundException e) {
System.out.println(e);
}
In this sample application, the same JavaBean can be used to retrieve information from two different
databases (DB2 for iSeries or DB2 for Windows). Property file jdbc400.properties contains all the
information needed to establish a connection with the iSeries, and property file jdbcwin.properties contains
the information to connect to DB2 for Windows. To help you see what the application retrieves from the
JDBC properties file, here are the contents I used:
JDBCDriver=com.ibm.as400.access.AS400JDBCDriver
protocol=jdbc:as400://
system=192.168.1.10/QIWS
user=SHALER
password=iseries
During my testing, the same table existed in both databases, so it was easy for me to substitute one database
for the other.
Better JavaBeans
After reading this article, studying the application, and installing and running it, you should be beginning to
understand why JavaBeans are considered so pluggable and reusable. The JavaBean
(CustomerLastNameBean) in the sample application can be easily used by virtually any application. Just
instantiate the CustomerLastNameBean, supply a valid customer number to its setCustLastName method,
and retrieve the customer's last name through the getCustLastName method.
Editor's Note: To install the application, see the CustomerLastNameInstallNotes.txt file included in the
download package.
|