XA
ASERT LOGO Advanced Software Engineering, Research and Training
Allowing Secure Applications to be Rapidly Developed and Deployed

An Introduction to Java Server PagesT and ServletsT

PART III: Development of a 3-tier Servlet/JSP Example
Author: Danielle Danielsson
Last Revised: 1st February 2001

In PART I of this series we briefly examined the benefits of a servlet, and had a look at what a servlet looks like from the inside. In PART II we were steamrolled by the JSP Actions, Directives and Objects, followed by a simple example that demonstrated some of these in action.

As mentioned earlier, a Java Servlet Page is actually nothing other than a servlet. The servlet engine compiles the JSP into a servlet when it is requested by the browser, executes any embedded Java code, and delivers the results to the browser in HTML format. A servlet is treated in a similar manner to the JSP; it is instantiated by the servlet engine and can remain available for other calls during the entire session, or just exist for the duration of the processing that the servlet needs to carry out and deliver to the browser.

3.1 Which to use, JSP or Servlet?

When constructing the architecture of a JSP/Servlet based application using the MVC (Model View Controller) pattern, then this technology would fit into the MVC framework as follows:

  • Model: JavaBeans - their main function is to encapsulate the processing of data.
  • View: JSP - used in the presentation layer of the application; this is the what the end-user sees and interacts with. Any Java code in the JSP should only be related to passing requests to the servlet and in retrieving data from a JavaBean.
  • Controller: Servlet - their capabilities are best utilized in routing user requests, and in managing the application's workflow. Some data pre-processing can also occur in this part of the application. The servlet should not be used to print out any html.

As we work through the upcoming example, the MVC roles discussed above will become clearer.

3.2 Application Architecture

Let's get on with developing a small application that demonstrates how the JSP/Servlet technology can be used.

We'll develop a web based phone book that searches a database, in this case a single table in a Microsoft SQL Server database.

The application consists of a search form with fields for first name and/or last name searches. The query is sent to the servlet which creates a query string. The servlet passes the query string to a JSP, which in turn communicates with a JavaBean to retrieve the data from the database.

Here is the design:

The images below demonstrate what the end result of our endeavours looks like.

 

 

3.3 Development of presentation layer

The script for the search form is shown in Listing 1. Since this page has no Java code to execute, it could just as easily have been a pure .html page.

Listing 1 : search_phone_book.jsp
<html>
<head>
<title>Search Phonebook</title>
</head>
<body bgcolor="#FFFFFF"> <p><b>
Search Company Phone Book</b></p>
<form name="form1" method="get" action="servlet/servlet_tutorials.PhoneBook.SearchPhoneBookServlet">
<table border="0" cellspacing="0" cellpadding="6"> <tr> <td >Search by</td> <td>
</td> </tr> <tr> <td><b>
First Name
</b></td> <td>
<input type="text" name="FirstName"> AND/OR</td> </tr> <tr> <td ><b>
Last Name
</b></td> <td >
<input type="text" name="LastName"></td> </tr> <tr> <td ></td> <td >
<input type="submit" name="Submit" value="Submit">
</td> </tr> </table>
</form>
</body>
</html>

After entering the search parameters into the form fields and pressing the submit button, the query parameters are sent to the SearchPhoneBookServlet, see Listing 2 below.

Listing 2 SearchPhoneBookServlet.java

package servlet_tutorials.PhoneBook;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import java.util.*;
import java.sql.*;
import java.net.*;

public class SearchPhoneBookServlet extends HttpServlet {

public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {

String query = null;
String where = null;
String firstname = null;
String lastname = null;
ResultSet rs = null;

res.setContentType("text/html");
PrintWriter out = res.getWriter();

// check which if any fields in the submitted form are empty
if (req.getParameter("FirstName").length() > 0)
firstname = req.getParameter("FirstName");
else firstname = null;

if (req.getParameter("LastName").length() > 0)
lastname = req.getParameter("LastName");
else lastname = null;

// Build sql query string
if ((firstname != null) && (lastname != null)){
where = "first_name ='";
where += firstname;
where += "' AND ";
where += "last_name ='";
where += lastname;
where += "'";
}
else if ((firstname == null) && (lastname != null)){
where = "last_name ='";
where += lastname;
where += "'";
}

else if ((firstname != null) && (lastname == null)){
where = "first_name ='";
where += firstname; where += "'";
}
query = "SELECT first_name,last_name,phone_number,e_mail
FROM PhoneBook WHERE " + where;

RequestDispatcher rd = null;
rd = getServletConfig().getServletContext().getRequestDispatcher("/display_search_results.jsp" +"?query=" + URLEncoder.encode(query));

// Route request to display_search_results.jsp.
if (rd != null) {
rd.forward(req, res);
}
}
}



Listing 3 display_search_results.jsp

<html>
<%@page import ="java.sql.*" %>
<jsp:useBean id="phone" class="servlet_tutorials.PhoneBook.PhoneBookBean"/>
<%@ page buffer=35 %>
<%@ page errorPage="error.jsp" %>

<html>
<head>
<title>Phone Book Search Results</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> </head>
<body bgcolor="#FFFFFF"> <b>Search Results</b> <p>
<% String q = request.getParameter("query");
ResultSet rs = phone.getResultSet(q);
%>
<% if (rs.wasNull()) {
%>

"NO RESULTS FOUND"
<%
} else
%>

<table> <tr> <td> <div align="center">First Name</b></div> </td> <td> <div align="center">Last Name</font></b></div> </td> <td> <div align="center">Phone Number</font></b></div> </td> <td> <div align="center">Email</font></b></div> </td> </tr>

<% while(rs.next()) { %> <tr> <td>
<%= rs.getString("first_name") %></td> <td><%= rs.getString("last_name") %></td> <td><%= rs.getString("phone_number") %>
</td> <td>
<%= rs.getString("e_mail") %>
</td> </tr>
<% } %>
</table>

3.4 Development of the data layer

Listing 4 shows the code for the PhoneBookBean which connects to the database,via ConnectDB class to retrieve the resultset.

Listing 4 PhoneBookBean.java
package servlet_tutorials.PhoneBook;
import java.io.*;
import java.net.*;
import java.sql.*;
import java.util.*;

public class PhoneBookBean {
private Connection con = null;
private Statement stmt = null;
private ResultSet rs = null;
private String query = null;

public PhoneBookBean() {}

public ResultSet getResultSet(String query) {
// grab a connection to the database
con = ConnectDB.getConnection();
try{
stmt = con.createStatement();
// run the sql query to obtain a result set
rs = stmt.executeQuery(query);
}
catch(SQLException sqlex){
sqlex.printStackTrace();
}
catch (RuntimeException rex) {
rex.printStackTrace();
}
catch (Exception ex) {
ex.printStackTrace(); }
return rs;
}
}

ConnectDB in Listing 5 is a re-usable class for setting up the connection to the database.

Listing 5 ConnectDB.java

package servlet_tutorials.PhoneBook;
import java.io.*;
import java.net.*;
import java.sql.*;
import java.util.*;

/**
* Re-usable database connection class
*/
public class ConnectDB {
// setup connection values to the database
static final String DB_DRIVER = "sun.jdbc.odbc.JdbcOdbcDriver";
static final String URL = "jdbc:odbc:PhoneBook";
static final String USERNAME = "anon_user";
static final String PASSWORD = "";

// Load the driver when this class is first loaded
static {
try {
Class.forName(DB_DRIVER).newInstance();
}
catch (ClassNotFoundException cnfx) {
cnfx.printStackTrace();
}
catch (IllegalAccessException iaex){
iaex.printStackTrace();
}
catch(InstantiationException iex){
iex.printStackTrace ();
}
}

/**
* Returns a connection to the database
*/
public static Connection getConnection() {
Connection con = null;
try {
con = DriverManager.getConnection(URL, USERNAME, PASSWORD);
}
catch (Exception e) {
e.printStackTrace();
}
finally {
return con;
}
}

/**
* Static method that releases a connection
* @param con the connection
*/
public static void closeConnection(Connection con) {
try {
if (con != null) con.close();
}
catch (Exception e) {
e.printStackTrace();
}
}
}

With a little bit of practice, the server-side Java world is your oyster! We have only started to prise open the shell to take a glimpse at the pearl inside, and it looks very attractive indeed.