Servlets as the implementation technique for Database application project

Harri Laine (4.2.2007)

Servlets

 

The programming technique originally demonstrated for the realisation of  Web-applications was the CGI technique (common gateway interface). In CGI the requested program is run in the server as a separate process. Programs may be written in any  programming language, also in Java. The best performance is achieved with compiled programs.  However, in practice, interpreted languages and just-in- time compiled languages have been most popular.  The best known example is Perl. Their performance is slowed down by the loading of the processing environment.  A lot of other things than just the program code must be loaded into the memory when setting up a process. This is also true forthe interpreted Java language. Loading and starting of the Java interpreter are quite heavy operations. The servlet technique was introduced as a  solution  to manage the loading problem and to run Java programs efficiently.  In this technique the basic idea is that the Java run time environment is started as an ongoing process.  The programs (servlets) will be loaded when they are called for the first time. They stay loaded into the run time  environment and thus may be started quickly when a new service request arrives. The  ongoing run time environment also makes it possible to store information in the main memory and thus to transfer it more quickly between  separate server programs. The idea of an ongoing environment process was presented in connection with Java but has later spread so that nowadays  many web-server products are able to  keep alive  Perl or PHP interpreters and load the program code only once.

Servlets are a  Java-based basic technique for the realisation of web-applications. For example, the JSP technique utilises servlets so that the JSP pages will be compiled as  servlets for execution. In  JSP pages the role of the HTML and the software code has been reversed as compared to standard servlets.  When using servlets an HTML page is produced with the Java output statements. In JSP the static HTML comprises the basis for the page where Java code may be included to produce the dynamic parts of the page.

A lot of information about servlets may be found in

The following articles are good for introduction:

A servlet consists of a primary Java class and any number of assisting classes. It is typically called by the name of the primary class but it may be renamed in the deployment description. Assisting classes may serve many servlets.

A run time environment is needed to host the servlets.  This environment is attached to a web server and to  a java run time environment.   A servlet will be loaded into the environment when it is called for the first time. It may be loaded also as soon as the environment is started or when the program code has been changed. This behaviour is, however, environment specific. Servlet classes, assisting classes, class libraries, static HTML pages and other files used in the application should be deployed so that the environment is able to locate and load them.

Servlets at the CS-department

Servlets need an environment to host them. The are many such environments (application server software) on the market. The Computer Science department uses the Apache Tomcat server. The server is installed on the users.cs.helsinki.fi computer.

Tomcat set up

To use Tomcat  you must first assign values for a few environment variables and specify the port that the server uses for requests.  The folder structure needed for deploying the application must also be constructed.  The ordering  script wanna-tomcat  takes care of most of these initialization tasks. This script needs to be run only once.  It

Starting and stopping the Tomcat server

The Tomcat server is started with the command start-tomcat and turned off with command stop-tomcat. Before these commands can be used, the environment should have been ordered using the command wanna-tomcat. When testing the application, it will be unnecessary to leave the server running if you don’t use it.

Deployment of the application in Tomcat

The files and programs of the application must be deployed according to the Tomcat specifications. The script wanna-tomcat creates the basic directrory structure. An examle loading script wanna tsoha completes it with an example application.
Let us call  the folder *user*/tomcat/webapps/ the TOMCAT folder (*user* is your username).

Directory structure

Let  APPLICATION be the root directory of the application. Its path is *user*/tomcat/webapps/*application_name*. The ordering script (wanna-tomcat) specifies the initial part of the path. You specify the name of the application yourself. Our example applications is called  'tsoha'. Tomcat is able to locate the components of the application if they are deployed as follows:

Servlet source code

It is recommended that the source code be kept separate from the deployment structure. The location of the servlet source code is not significant.  The compiled *.class files must be copied to the deployment folder for the execution.

In our example environment source codes are kept in folder APPLICATION/src/

Compiling the servlets

Environment variable CLASSPATH has an important role in Java. All the libraries and external classes must be located in folders that are listed in the CLASSPATH. This is true for both compilation and execution. Database driver is an exception. Its path need not be included in the compile CLASSPATH. You may use the command setup tomcat to modify the CLASSPATH to include the libraries that belong to the Tomcat installation.  If  there are local packages and libraries in the APPLICATION/WEB-INF/lib folder these must be included in the compile CLASSPATH.  Ant software can be used to control the compilation and  deployment. There is a separate instruction on the use of ant.

Servlet calls in URLs

Servlet URLs are constructed as defined in files  *application_name*.xml and web.xml . By default the URL is of form http://t-*user*.users.cs.helsinki.fi/*application_name*/servlet/*Servlet_name*
Static pages located in folder APPLICATION are referred to with URLs of form
http://t-*user*.users.cs.helsinki.fi/*application_name*/*page_name.html*

For example, http://t-laine.users.cs.helsinki.fi/tsoha/servlet/PgTesti identifies the servlet PgTesti that belongs to the example application tsoha.

Servlet lifespan

A servlet consists of one Java class which inherits the library class HttpServlet. The class can utilise other Java classes. The actual service is provided by  the service methods doPost and  doGet. Which one of the methods is started to take care of the service request depends on the call. If the call is given through an HTML link or an HTML-form is defined to be handled using method 'get', then the method doGet will provide the service,  otherwise  doPost  is the service provider. In several cases it may be a good idea to program both methods to provide the same service. The service can then be requested both from a link and as a form handler. If you want to be sure that request parameters are not included in the URL and that they are not visible in the address field of the browser, you should use a form haldler and the method 'post' in issuing the request.

When the servlet engine receives a request for the servlet it starts the service as a new thread. There may be parallel threads running the same code. The service methods must be coded as thread safe. In other words, it must be possible to run them in parallel without them messing up each other's data. This is achieved the simplest by using only the local variables and objects in the service methods.

When information about the session state is needed this should be transmitted through the web pages and the browser. Hidden fields and cookies may be used for this.  If class or object variables of the servlet class are used, their assignment operations must be protected against parallel use.

The lifespan of a servlet consists of the initialization, the service stage and the removal.

Initialization of a servlet takes place after the servlet code has been loaded into the servlet engine.  During the initialization a single object of the class is created and its init method is run. Tasks that may be done in the init method may include setting up the class variables and loading the database driver. The init method is executed only once.

The service stage consists of repeated executions of  the doGet and doPost methods. They carry out  their service as threads (a kind of lightweight process). Each call is taken care of as a separate thread. The values of the variables within the method (the state of the method) are lost when the execution of the method ends.

Removal takes place when the servlet is removed from the engine. This happens, for example, when the server is closed. If there are any clean-up operations to be done, they should be coded as the destroy method.

Servlet API

The servlet interface has been defined in J2EE specifications as javax.servlet and javax.servlet.http packages. These must be included in the program with import. In addition, a library to implement the interfaces must be available and included in the CLASSPATH.  The implementation library servlet.jar that is included in the Tomcat installation ($CATALINA_HOME/common /lib/servlet.jar). This package must be included also  in the compile CLASSPATH.

All servlet classes  have to inherit the class HttpServlet. This specifies the signatures of the service methods  doGet and doPost There are also some other service methods, for example, for file upload.

public void doPost(
   HttpServletRequest req, HttpServletResponse resp) 
        throws ServletException, IOException { ...}

All service methods have two parameters HttpServletRequest and HttpServletResponse  objects. The HttpServletRequest object offers services for handling of the request parameters. The HttpServletResponse object delivers the  result of the service to the web browser.

The Service

Preparing to serve

Preliminary actions  typically include:

Reconstruction of the state of the session

HttpSession objects provide a convenient way to store the state of  the session. Any objects may be stored in a HttpSession object as values of its attributes, the names of which you assign yourself.  The getSession method of the HttpServletRequest object either creates a new HttpSession object or locates the one previously created for the same session.  The servlet engine takes care of sending the session identifier as a cookie to the browser and  picking up the identifier from the cookie received with the request. There are also other techniques for transmitting the session identifiers.  HttpSession object has methods setAttribute and getAttribute for storing and locating the stored objects. The reconstruction of the  state of the session must be made very first before any results are written.

Cookies and hidden form fields may be used instead of the HttpSession object for transmitting information between servlets. State information may also be stored in the database.  

Preparations for output

Some preliminary actions must be carried out before any output may be produced. They include

  • definition of the type of the result, and
  • selection of the output ‘device’

The following code shows one way of doing this:

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

In addition, one might construct web page title information at this phase..  If many servlets share the same title information, one could define a separate class to provide these and other common parts of the pages. Another way is to define a new class in the class hierarchy, between the HttpServlet and your own servlet classes.

Extracting the request parameter values

From the callers point of view request parameters for servlets are similar to the request parameters when using CGI. The service method may access the parameters by asking the HttpServletRequest object for the parameter values for a given parameter name:

String value = req.getParameter("parameter_name");

The value is provided as a String object. If the value is something else, it should be transformed.  If no value was provided in the request for the given name, the result is a null.  If the same paramerer name appears many times in the parameter set, the values of the parameter should be extracted using method  getParameterValues, which produces a String array.

Establishing a database connection

When the  servlet uses a database, the forming of the database connection is also a typical preliminary action. If a connection pool is used, a connection is requested from the pool.  However, study projects are not allowed to use pools of open connections. 

To create a connection a database-specific driver must be loaded  first. This driver provides a method for creating connections.  It might be useful to define a class to take care of database connections. This class may be between  HttpServlet and your own servlet classes in the class hierarchy, as is the case with our example class  DatabaseServlet. This class requires that specifications for the connections are given in a separate configuration file (an example of a configuration file). The address of the configuration file is given in  the web.xml file  (here is an example of how to define the address). The database connections rely on a database driver. A driver for our  Oracle database is /opt/oracle/jdbc/lib/ojdbc14.jar. and it should be copied in  APPLICATION/WEB INF/lib/ folder.

N.B.: Our setup command for oracle setup oracle includes the above-mentioned driver in the CLASSPATH. If this command has been issued in the session before the start-tomcat command , the driver will also be included in the runtime CLASSPATH.  If tomcat is started this way, APPLICATION/WEB INF/lib/ should not contain a copy of the driver.  If you copy the driver, you should not issue the setup oracle command before starting Tomcat.

A connection to a postgerSQL database running in db.cs.helsinki.fi under user account username  is created as:

Connection conn = createConnection("org.postgresql.Driver",
"jdbc:postgresql://localhost/username",
username,password);

Here, portnumber is the one provided by  wanna-postgres script and username is the account name.

The driver for  PostgreSQL may be found in /opt/jdbc/jdbc7.0-1.2.jar.

Service body

What is in the body of the service depends on what the service method is to do. Even the most simple service constructs a new web page in HTML format. A text is written on the page by using the printing device  (above PrintWriter ) attached to the HttpServletResponse object. One design pattern is to construct a form with the same servlet that handles the form after it has been filled.

Database operations

A Statement or a PreparedStatement  object is  created to carry out most of the database operations. CallableStatement objects can used for executing  database procedures and functions. PreparedStetement and CallableStatement  classes inherit the Statement class. Next, all the objects of these classes are called statement objects. The statement objects are created using methods of the Connection object They must always be closed before exiting the program. Nearly all the database operations can cause a SQLException exception, which must be caught in the program. It is not necessary to embed database processing directly in the code of service methods, a separate database interface class might be a good idea.

In the following example of the database loop:

   
Statement stm=null;
ResultSet rs=null;
String kysely= 
   "select nimi from opiskelija where hetu like \'0101%\' order by nimi";
// born 1st of january
try  {
    stm= conn.createStatement();
    rs= stm.executeQuery(kysely);
    while (rs.next()) {
        pw.println(rs.getString("nimi")+"<br>");
    }
} catch (SQLException e) {
     databaseError(e.getErrorCode(), e.getMessage(), pw);
// databaseError is a private error method
} 
// finally assures that close is done
finally { 
    try {
       if (rs!=null)
          rs.close();
	 if (stm!=null)
          stm.close();
    } catch (SQLException ee) {}
 }

Ending the service

As a last step of the service method the database resources must be freed and an HTML page must be ended. The freeing of database resources includes closing ResultSets and Statements by the calling the close methods of these objects. In the JDBC manual it is stated that this is not usually necessary because the Java garbage collector takes care of the matter. However, some database servers (also Oracle) require that the resources are explicitly freed by calling the close methods.

Examples

The example application is deployed as follows:

~laine/tomcat/webapps

 

tsoha.xml ( the browser may have its own style for xml, save it for examination)

~laine/tomcat/webapps/tsoha

 

esim.html

 

alkukuva.jpg - an image

 

tyyli.css - a style sheet

 

nappi2.gif - an image

 

testing.gif -an image used in servlet only

~laine/tomcat/webbapps/tsoha/WEB-INF

 

web.xml (the browser may have its own style for xml, save it for examinationi)

~laine/tomcat/webapps/tsoha/WEB-INF/classes

 

ServletTest.class

SessionTest.class

PgTest.class

~laine/tomcat/webapps/tsoha/WEB-INF/lib

 

ojdbc14..jar - Oracle JDBC-driver

~laine/tomcat/webapps/tsoha/src

 

ServletTest.java

SessionTest.java (ServletTest, modified to include a simple test for sessions, counts the number of requests served within this session)