The whole idea behind creating Data
Access Objects is to deliver them to other application developers,
such as JSF or Struts developers, and allow those developers to
interact with the back end database without any great deal of
knowledge of how the back end is implemented. Seeing that we just
spent some time implementing the DAO design pattern around our User
class, it only makes sense that we demonstrate how to really take
advantage of that DAO and integrate it into a web based application.
The focus of this tutorial will be to
create a relatively simple and straight-forward web based application
that leverages JSPs, JSTL custom tags, and a few intelligently placed
scriptlets that will mitigate database access through the use of the
UserDAO class.
Please...Cut Me Some Slack
Now I just want to point out the fact
that the goal here is not to develop the worlds greatest MVC
application. At the very least, a production environment should be
using Servlets and JSPs, if not Struts, JSF or Seam. But this tutorial
isn't about web design - it's about Hibernate. This example will show
you a very interesting, exciting, and simple web site that leverages
the Hibernate code we have written so far. However, it does not employ
the most elegant Model-View-Controller ethics. Furthermore, this
chapter won't try and explain JSP development and deployment. I'm
sorry, but that's a 1500 page book in itself. This chapter is here to
provide a simple idea of how the Hibernate code we have written might
fit into a very simple, web-based application. If you have no idea
what HTML is, or how a Java Server Page works, or how to deploy a JSP
to a Servlet engine like Tomcat or WebSphere, you might be better off
skipping this chapter and going right into the sections on mappings
and advanced DAOs.
The user.jsp User Interface
The goal of this tutorial is to create a
very simple, user friendly, web based application that allows a user
to add, update, delete, and do custom searches against the user table
in the database. The finished product will look something like this:
To help describe how this application
will work, I'm going to quickly go over all of the command buttons and
action links you see on this user interface, and briefly describe
their purpose.
The Clear Command Button
At various times, incorrect data will be
typed into the textfields that needs to be cleared by the end user. If
someone clicks on the Clear command button, the four textfields are
cleared.
NOTE: on some screenshots, the Clear
button may be cropped off, just to get the content formatted on the
screen a little bit better. My apologies if it catches you off guard.
Adding Records: The Create Command
Button
If an end user types in a name, password
and email address, clicking on Create will add a new record to the
database. The id field is read-only in this application, so a user
cannot type in an id. Instead, Hibernate will generate a unique id for
new records.
Updating & Deleting Records
Below the command buttons such as Update
and Create, a summary of each record in the database will be listed.
To the left of each record listed are two separate command links, one
named edit and the other named delete. Clicking the delete link will
delete the record in question. However, clicking on the edit link will
have the textfields populated with information pertinent to that
record. From there, if the Update button is pressed, the corresponding
record in the database is updated.
Notice that when a record is selected for
editing, the id textfield gets populated. This is a read-only field
that cannot be edited, but it can be used for display purposes.
Search Functionality
The search functionality is probably the
neatest part of the application. The application client can type into
any of the editable text fields and perform a search. If they click
the Strict Search command button, they will be returned a list
of records that match exactly on what was typed into the textfields:
The Fuzzy Search
In contrast to the Strict Search, if a
user types values into the textfields and clicks on the Fuzzy
Search command button, then records that match the given fields anywhere
in the corresponding properties are returned and listed:
The Basic HTML for the JSP Page
To develop this web based application,
the first thing you need to do is create a very simple JSP page, named
user.jsp, with an open and closed form tag that links its action back
to itself, the user.jsp page
<html>
<body>
<form action="user.jsp"> </form>
</body>
</html>
Adding the Textfields
The JSP page will have four input fields
for displaying the user's id, loginName, emailAddress and password
properties, with the id being read-only. So, the HTML grows:
<html><body><form action="user.jsp">
<!-- Here are our four textfields -->
<input type="text" size="7"
readonly name="id" value=""> Id
<BR/>
<input type="text" size="30"
name="loginName" value=""> Name
<BR/>
<input type="text" size="30"
name="password" value=""> Password
<BR/>
<input type="text" size="30"
name="emailAddress" value=""> Email
<BR/></form></body></html>
Notice how the value of each field uses
an expression, such as . These expressions will
automatically populate the text fields with data if a user instance
has been selected for display. They'll make life significantly easier
for us, that's for sure!
Note that the names of the textfields
match the properties of the User class. This is not by accident. If
the names of the textfields do not match the case sensitive names of
the properties in the User class, the JSP will not work properly.
Adding the Command Buttons
When a client using our application
clicks on a button or a link, it will generate a command, such as
Update, Edit, Delete or Search, and that command needs to be executed.
Our application will have seven commands, five of which will be
triggered by buttons, the other two of which will be triggered by
links.
The five buttons our application
uses will include: Strict Search, Fuzzy Search, Update, Create and
Clear. Edit and delete commands will be triggered by links on
the page.
Here is the HTML code for the five
buttons, which will go under the textfields, and inside the <form
/> </form> tags.
<!-- Here are all of our buttons!!! -->
<input type="submit" name="command" value="Strict Search">
<input type="submit" name="command" value="Fuzzy Search">
<input type="submit" name="command" value="Update">
<input type="submit" name="command" value="Create">
<input type="submit" name="command" value="Clear">
Notice that each button, while displaying
a different value on the JSP page, has the same name: command.
This is important, as the logic in the JSP page will inspect the name
of the command button and subsequently execute logic based on which
button was pressed. The logic for responding to the client clicking on
a particular button looks something like this:
String command=request.getParameter("command");
if (command != null) {
if (command.equals("Create")) {
userDAO.create(user);
}
}
JSTL forEach and the Taglib Directive
Along with all of the handsome buttons,
the JSP will also display a listing of users. If a search has been
performed, the JSP will display the results of that search. If no
search has been performed, the JSP will list all of the users in the
database.
To achieve this listing of users, the JSP
will always ensure that a java.util.List, containing instances of the
User class, is placed in the request scope with the identifying name
of users. As such, a simple JSTL custom tag can easily loop
through that list, and display basic information about each user, one
record at a time. Here's how the JSTL loop would look:
<c:forEach items="" var="user">
| <c:out value="" />
| <c:out value="" />
| <c:out value="" />
| <br/>
</c:forEach>
The Required JSTL Taglib Directive
It should also be noted that in order to
use the JSTL tag libraries, you need a taglib directive at the top of
the JSP. You can place it right before the <HTML> tag.
<%@ taglib prefix="c"
uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
Creating the Edit URL
The JSTL forEach tag is used to loop
through every entity in the list of users that is placed in the
request scope. However, what would be really nice is to have a little
link that says edit right before the first data field is displayed, so
that if the end user clicks on it, the details of the user in question
will be displayed in the JSP's textfields. To do this, we need to
create a link that displays the word edit, is associated with a
command named edit, and of course, has the id of the user being edited
so that our JSP knows which user will have its data displayed.
This becomes a bit mucky. Inside the
forEach loop, you need to create a new URL named editurl that links
back to the user.jsp page. Here's how it looks initially:
<c:url var="editurl" value="user.jsp" >
</c:url>
Of course, we want the link to trigger a
command named edit, and we also want the link to be associated with
the id of the user being displayed on the given row. This requires the
following two param tags to be added within the url tag:
<c:url var="editurl" value="user.jsp" >
<c:param name="command" value="edit" />
<c:param name="id" value=""/>
</c:url>
Of course, this only builds a url that
can be referenced by the variable name editurl. To actually have this
display as a clickable link, we need to use the anchor tag and
reference the editurl.
| <a href="">edit</a>
Creating the Delete URL
In almost the same way that we created
the edit URL inside of the JSTL forEach loop, we need to create a link
that will trigger the delete command.
You will notice that the deleteurl is
almost identical to the editurl, except the var has changed from
editurl to deleteurl, and the value of the first param tag is delete,
associating the link with the delete command.
<c:url var="deleteurl" value="user.jsp" >
<c:param name="command" value="delete" />
<c:param name="id" value=""/>
</c:url>
| <a href="">delete</a>
After all of the crazy URLs are created
and prepared for page display, the messy forEach JSTL loop looks like
this:
<c:forEach items="" var="user">
<c:url var="editurl" value="user.jsp" >
<c:param name="command" value="edit" />
<c:param name="id" value=""/>
</c:url>
<c:url var="deleteurl" value="user.jsp" >
<c:param name="command" value="delete" />
<c:param name="id" value=""/>
</c:url>
| <a href="">edit</a>
| <a href="">delete</a>
| <c:out value="" />
| <c:out value="" />
| <c:out value="" /> |<br/>
</c:forEach>
:::The JSP Page So Far:::
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html><body>
<form action="user.jsp">
<!-- Here are our four textfields -->
<input type="text" size="7" readonly name="id"
value=""> Id <BR/>
<input type="text" size="30" name="loginName"
value=""> Name <BR/>
<input type="text" size="30" name="password"
value=""> Password <BR/>
<input type="text" size="30" name="emailAddress"
value=""> Email <BR/>
<!-- Here are all of our buttons!!! -->
<input type="submit" name="command" value="Strict Search">
<input type="submit" name="command" value="Fuzzy Search">
<input type="submit" name="command" value="Update">
<input type="submit" name="command" value="Create">
<input type="submit" name="command" value="Clear"> <BR>
<c:forEach items="" var="user">
<c:url var="editurl" value="user.jsp" >
<c:param name="command" value="edit" />
<c:param name="id" value=""/>
</c:url>
<c:url var="deleteurl" value="user.jsp" >
<c:param name="command" value="delete" />
<c:param name="id" value=""/>
</c:url>
| <a href="">edit</a>
| <a href="">delete</a>
| <c:out value="" />
| <c:out value="" />
| <c:out value="" /> | <BR/>
</c:forEach>
</form>
</body></html>
Directives, UseBeans and Property
Setters
We've actually got three more JSP related
tags that we need to add to our JSP page before we start in on the
actual logic. The first is a page directive, which will provide all of
the required package imports. We can place this anywhere on the page,
although towards the top, right next to the taglib directive, is
perhaps the most handsome spot.
<%@page
import="com.examscam.dao.*,com.examscam.model.*,
com.examscam.*,org.hibernate.*;"
contentType="text/html; %>
After the @page directive, we want a
useBean and a setProperty tag to manage an instance of the User class.
This instance will be creatively named user. Here's how it looks:
<jsp:useBean class="com.examscam.model.User"
id="user" scope="request"/>
<jsp:setProperty name="user" property="*" />
The useBean tag is just a simple way of
declaring an instance variable to be used on the page. Essentially, it
instructs the JSP runtime to look for an instance of the User class,
which will be named user, in the request scope. If there isn't one in
the request scope, the JSP engine will create one by calling the
default constructor of the User class and placing it in there.
Basically, it ensures that an instance of the User class, with the
variable name of user, is always available when the JSP runs.
The setProperty tag has the effect of
initializing all of the properties of the User instance, named user,
with like-named textfields when the JSP page is submitted. So, if
someone types "Cameron" into the loginName textfield, and "passw0rd"
into the password textfield, then the jsp:setProperty will see to it
that the loginName and password fields of the User instance named user
are initialized accordingly. It's all really neat.
<%@page import="com.examscam.dao.*,com.examscam.model.*,
com.examscam.*,org.hibernate.*;" contentType="text/html;%>
<jsp:useBean
class="com.examscam.model.User"
id="user" scope="request"/>
<jsp:setProperty name="user" property="*" />
<%@ taglib prefix="c"
uri="http://java.sun.com/jsp/jstl/core" %>
<html><body>
<form action="user.jsp">
<!-- Here are our four textfields -->
<input type="text" size="7" readonly name="id"
value=""> Id <BR/>
<input type="text" size="30" name="loginName"
value=""> Name <BR/>
<input type="text" size="30" name="password"
value=""> Password <BR/>
<input type="text" size="30" name="emailAddress"
value=""> Email <BR/>
<!-- Here are all of our buttons!!! -->
<input type="submit" name="command" value="Strict Search">
<input type="submit" name="command" value="Fuzzy Search">
<input type="submit" name="command" value="Update">
<input type="submit" name="command" value="Create">
<input type="submit" name="command" value="Clear"> <BR>
<c:forEach items="" var="user">
<c:url var="editurl" value="user.jsp" >
<c:param name="command" value="edit" />
<c:param name="id" value=""/>
</c:url>
<c:url var="deleteurl" value="user.jsp" >
<c:param name="command" value="delete" />
<c:param name="id" value=""/>
</c:url>
| <a href="">edit</a>
| <a href="">delete</a>
| <c:out value="" />
| <c:out value="" />
| <c:out value="" /> | <BR/>
</c:forEach>
</form>
</body></html>
The Java Scriptlet Logic
With the HTML and custom tags all added
into the JSP, we can start concentrating on the logic required to
implement our multi-faceted JSP page.
Immediately following our jsp:setProperty
tag, we will add a JSP scriptlet, which is delineated with the
following tag: <% %>. Basically, every piece of Java code we
write that is part of this scriptlet must be contained within the two
percentage signs.
Our scriptlet will start off simple
enough, with the simple initiation of a transaction using the
HibernateUtil class. From there, we will declare and initialize the
UserDAO instance. Then we will declare a java.util.List object named
users, and initialize this list to null. This list will eventually be
populated, and the contents of the list will be displayed by the JPS's
forEach JSTL loop.
<%
HibernateUtil.beginTransaction();
UserDAO userDAO = new UserDAO();
java.util.List users = null;
%>
Which Button Was Pressed?
After beginning a transaction, and doing
a little declaration and initializations with the UserDAO and
java.util.List classes, we go to the request object and ask it which
button or link the user has pressed to trigger this page to appear.
Each button or link on the page is associated with the word command,
so to find out which action was invoked, we simply ask the request
object to return the value associated with the parameter "command".
<%
HibernateUtil.beginTransaction();
UserDAO userDAO = new UserDAO();
java.util.List users = null;
String command=request.getParameter("command");
%>
Responding to the Client Request
Our JSP is pretty much focused around
responding to which one of the seven command actions were invoked.
Correspondingly, the bulk of the JSP scriptlet will involve reacting
to one of the seven commands. A skeleton of the scriptlet, without any
logic placed in the body of the if blocks, would look like this:
<%
HibernateUtil.beginTransaction();
UserDAO userDAO = new UserDAO();
java.util.List users = null;
String command=request.getParameter("command");
if (command != null) {
if (command.equals("Create")) {/*do something*/}
if (command.equals("Update")) {/*do something*/}
if (command.equals("edit")) {/*do something*/}
if (command.equals("delete")) {/*do something*/}
if (command.equals("Fuzzy Search")){/*do something*/}
if (command.equals("Strict Search")){/*do something*/}
if (command.equals("Clear")) {/*do something*/}
}
%>
Notice that the first if statement is a
check for null. The command will be null if the page is being invoked
for the first time, or simply being refreshed. Not checking for a null
command will trigger a potential NullPointerException.
Harking back to the buttons that were
added to the page, you can see that the command names being used map
back to the values associated with the various buttons that were added
to the page:
<input type="submit" name="command" value="Strict Search">
<input type="submit" name="command" value="Fuzzy Search">
<input type="submit" name="command" value="Update">
<input type="submit" name="command" value="Create">
<input type="submit" name="command" value="Clear">
The buttons represent five of the
possible commands. The other two commands, edit and delete, are
similarly triggered by anchor links coded in the JSTL forEach loop.
Your Wish is my Command
So, what do we do when we encounter a
Create command? Well, the useBean tag has already initialized a User
instance, named user, for us, and the setProperty tag has initialized
the values of that User instance to whatever the application client
typed into the loginName, emailAddress and password textfields. So,
with a fully initialized User instance at our fingertips, all we need
to do is pass that instance to the create method of the already
declared and initialized UserDAO:
if (command.equals("Create")) {
userDAO.create(user);
}
And what do we do if the client has
triggered an update command? Well, it's the same thing, except it's
different. :) With the update command, we pass the initialized User
instance to the UserDAO's update method:
if (command.equals("Update")) {
userDAO.update(user);
}
Do you want to guess what you do for the
Delete command? Yeah, it's pretty similar.
if (command.equals("delete")) {
userDAO.delete(user);
request.setAttribute("user", null);
}
One thing to notice about the delete
command implementation is that it actually nulls out the user instance
sitting in the request scope. We need to do this, because if the user
instance stays in the request scope, the JSP engine will try to
repopulate the textfields on the page with the user instance's values
the next time the page renders. Nulling out the user instance in the
request scope will stop any textfield rendering of the deleted user's
properties.
We're in the Clear
The clear method is intended just to
clear the textfields of their current values. As such, the Clear
command does not actually involve the UserDAO at all, but instead,
just pulls the same trick the delete method pulled when it nulled out
the User instance in the request scope:
if (command.equals("Clear")) {
request.setAttribute("user", null);
}
The edit Command
The edit command shakes things up a
little bit by invoking a finder method. The edit command will give us
access to the id of the user for which the application client wants
to see more information. Given the id, we can use the findByPrimaryKey
method of the UserDAO to obtain the unique user. From there, we do the
opposite of nulling out the user in the request scope by instead,
stuffing the user we just found into the request scope. Thus, when the
JSP re-renders, the JSP engine will display the properties of this
user in the appropriate textfields.
if (command.equals("edit")) {
user = userDAO.findByPrimaryKey(user.getId());
request.setAttribute("user", user);
}
Strict and Fuzzy Searches
The search commands, Fuzzy Search and
Strict Search, are both very similar, but different from the other
commands in the fact that they pass the singular user instance into
their finder methods, but get a collection, or List, of user instances
in return. Notice that the findByExample method returns a collection
of user instances that are used to initialize the java.util.List
variable named users, which was originally initialized to null at the
beginning of the JSP scriptlet.
if (command.equals("Fuzzy Search")) {
users = userDAO.findByExample(user, true);
}
if (command.equals("Strict Search")) {
users = userDAO.findByExample(user, false);
}
The fuzzy and strict searches differ only
by the Boolean value passed into the findByExample method. When the
Boolean value is true, a fuzzy search is performed, while a strict
search is performed when the Boolean value is set to false.
Making Sure the Users List is
Initialized
We have seen the java.util.List named
users initialized by the fuzzy and strict search commands. However, if
the client has invoked a different command, the users List remains
null after we have run through all of the command logic. So, after all
the commands have executed, it's prudent to check to see if the users
List is null, and if it is, we call the findAll method of the UserDAO
to provide a fruitful initialization. We then place the users List
into the request scope for future retrieval by other parts of the
application.
if (users == null) {
users = userDAO.findAll();
}
request.setAttribute("users", users);
HibernateUtil.commitTransaction
When all is said and done, the scriptlet
ends with a termination of the database transaction that made all of
this wonderful JSP coding experience possible. Here's the full
scriptlet:
<%
HibernateUtil.beginTransaction();
UserDAO userDAO = new UserDAO();
java.util.List users = null;
String command = request.getParameter("command");
if (command != null) {
if (command.equals("Create")) {
userDAO.create(user);
}
if (command.equals("Update")) {
userDAO.update(user);
}
if (command.equals("edit")) {
user = userDAO.findByPrimaryKey(user.getId());
request.setAttribute("user", user);
}
if (command.equals("delete")) {
userDAO.delete(user);
request.setAttribute("user", null);
}
if (command.equals("Fuzzy Search")) {
users = userDAO.findByExample(user, true);
}
if (command.equals("Strict Search")) {
users = userDAO.findByExample(user, false);
}
if (command.equals("Clear")) {
request.setAttribute("user", null);
}
}
if (users == null) { users = userDAO.findAll(); }
request.setAttribute("users", users);
HibernateUtil.commitTransaction();
%>
The Whole JSP!!!
<%@page
import="com.examscam.dao.*,com.examscam.model.*,
com.examscam.*,org.hibernate.*;" contentType="text/html; %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<jsp:useBean class="com.examscam.model.User" id="user"
scope="request"/>
<jsp:setProperty name="user" property="*" />
<%
HibernateUtil.beginTransaction();
UserDAO userDAO = new UserDAO();
java.util.List users = null;
String command = request.getParameter("command");
if (command != null) {
if (command.equals("Create")) {
userDAO.create(user);
}
if (command.equals("Update")) {
userDAO.update(user);
}
if (command.equals("edit")) {
user = userDAO.findByPrimaryKey(user.getId());
request.setAttribute("user", user);
}
if (command.equals("delete")) {
userDAO.delete(user);
request.setAttribute("user", null);
}
if (command.equals("Fuzzy Search")) {
users = userDAO.findByExample(user, true);
}
if (command.equals("Strict Search")) {
users = userDAO.findByExample(user, false);
}
if (command.equals("Clear")) {
request.setAttribute("user", null);
}
}
if (users == null) {
users = userDAO.findAll();
}
request.setAttribute("users", users);
HibernateUtil.commitTransaction();
%>
<html>
<body><form action="user.jsp">
<!-- Here are our four textfields -->
<input type="text" size="7"
readonly name="id" value=""> Id
<BR/>
<input type="text" size="30"
name="loginName" value=""> Name
<BR/>
<input type="text" size="30"
name="password" value=""> Password
<BR/>
<input type="text" size="30"
name="emailAddress" value=""> Email
<BR/>
<!-- Here are all of our buttons!!! -->
<input type="submit" name="command" value="Strict Search">
<input type="submit" name="command" value="Fuzzy Search">
<input type="submit" name="command" value="Update">
<input type="submit" name="command" value="Create">
<input type="submit" name="command" value="Clear">
<BR>
<c:forEach items="" var="user">
<c:url var="editurl" value="user.jsp" >
<c:param name="command" value="edit" />
<c:param name="id" value=""/>
</c:url>
<c:url var="deleteurl" value="user.jsp" >
<c:param name="command" value="delete" />
<c:param name="id" value=""/>
</c:url>
| <a href="">edit</a>
| <a href="">delete</a>
| <c:out value="" />
| <c:out value="" />
| <c:out value="" />
|
<BR/>
</c:forEach>
</form>
</body>
</html>
Deploying the user.jsp
The user.jsp has to be the simplest of
all web based applications that might leverage the Hibernate framework. To
deploy the user.jsp page, you must place the user.jsp page in a
working deployment directory of a Servlet engine such as Tomcat.
Furthermore, you must make sure that all of the Hibernate libraries
and the custom Java code use by the JSP, such as the HibernateUtil
class and the User class, are on the classpath of the Servlet engine.
Typically, web based applications are
deployed as war files. If a war file was being deployed, the user.jsp
page would be placed in the root of the war file, while the required
libraries would go in the WAR file's WEB-INF\lib directory, and
compiled source code would be placed in the WEB-INB\classes directory.
When deployed to the open source Tomcat
Servlet engine, the user.jsp page creates a very handsome and easy to
use, user management dashboard type of application:

|