Sunday, 8 July 2012

Servlets - File Uploading


A Servlet can be used with an HTML form tag to allow users to upload files to the server. An uploaded file could be a text file or image file or any document.

Creating a File Upload Form:

The following HTM code below creates an uploader form. Following are the important points to be noted down:
  • The form method attribute should be set to POST method and GET method can not be used.
  • The form enctype attribute should be set to multipart/form-data.
  • The form action attribute should be set to a servlet file which would handle file uploading at backend server. Following example is using UploadServlet servlet to upload file.
  • To upload a single file you should use a single <input .../> tag with attribute type="file". To allow multiple files uploading, include more than one input tags with different values for the name attribute. The browser associates a Browse button with each of them.
 
<html>
<head>
<title>File Uploading Form</title>
</head>
<body>
<h3>File Upload:</h3>
Select a file to upload: <br />
<form action="UploadServlet" method="post"
                        enctype="multipart/form-data">
<input type="file" name="file" size="50" />
<br />
<input type="submit" value="Upload File" />
</form>
</body>
</html>

This will display following result which would allow to select a file from local PC and when user would click at "Upload File", form would be submitted along with the selected file:

 
File Upload: 
Select a file to upload: 
 
 

 
 

 
NOTE: This is just dummy form and would not work.

Writing Backend Servlet:

Following is the servlet UploadServlet which would take care of accepting uploaded file and to store it in directory <Tomcat-installation-directory>/webapps/data. This directory name could also be added using an external configuration such as a context-param element in web.xml as follows:
 
<web-app>
....
<context-param> 
    <description>Location to store uploaded file</description> 
    <param-name>file-upload</param-name> 
    <param-value>
         c:\apache-tomcat-5.5.29\webapps\data\
     </param-value> 
</context-param>
....
</web-app>

Following is the source code for UploadServlet which can handle multiple file uploading at a time. Before procedding you have make sure the followings:
  • Following example depends on FileUpload, so make sure you have the latest version ofcommons-fileupload.x.x.jar file in your classpath. You can download it fromhttp://commons.apache.org/fileupload/.
  • FileUpload depends on Commons IO, so make sure you have the latest version ofcommons-io-x.x.jar file in your classpath. You can download it fromhttp://commons.apache.org/io/.
  • While testing following example, you should upload a file which has less size thanmaxFileSize otherwise file would not be uploaded.
  • Make sure you have created directories c:\temp and c:\apache-tomcat-5.5.29\webapps\data well in advance.
// Import required java libraries
import java.io.*;
import java.util.*;
 
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.output.*;

public class UploadServlet extends HttpServlet {
   
   private boolean isMultipart;
   private String filePath;
   private int maxFileSize = 50 * 1024;
   private int maxMemSize = 4 * 1024;
   private File file ;

   public void init( ){
      // Get the file location where it would be stored.
      filePath = 
             getServletContext().getInitParameter("file-upload"); 
   }
   public void doPost(HttpServletRequest request, 
               HttpServletResponse response)
              throws ServletException, java.io.IOException {
      // Check that we have a file upload request
      isMultipart = ServletFileUpload.isMultipartContent(request);
      response.setContentType("text/html");
      java.io.PrintWriter out = response.getWriter( );
      if( !isMultipart ){
         out.println("<html>");
         out.println("<head>");
         out.println("<title>Servlet upload</title>");  
         out.println("</head>");
         out.println("<body>");
         out.println("<p>No file uploaded</p>"); 
         out.println("</body>");
         out.println("</html>");
         return;
      }
      DiskFileItemFactory factory = new DiskFileItemFactory();
      // maximum size that will be stored in memory
      factory.setSizeThreshold(maxMemSize);
      // Location to save data that is larger than maxMemSize.
      factory.setRepository(new File("c:\\temp"));

      // Create a new file upload handler
      ServletFileUpload upload = new ServletFileUpload(factory);
      // maximum file size to be uploaded.
      upload.setSizeMax( maxFileSize );

      try{ 
      // Parse the request to get file items.
      List fileItems = upload.parseRequest(request);
 
      // Process the uploaded file items
      Iterator i = fileItems.iterator();

      out.println("<html>");
      out.println("<head>");
      out.println("<title>Servlet upload</title>");  
      out.println("</head>");
      out.println("<body>");
      while ( i.hasNext () ) 
      {
         FileItem fi = (FileItem)i.next();
         if ( !fi.isFormField () ) 
         {
            // Get the uploaded file parameters
            String fieldName = fi.getFieldName();
            String fileName = fi.getName();
            String contentType = fi.getContentType();
            boolean isInMemory = fi.isInMemory();
            long sizeInBytes = fi.getSize();
            // Write the file
            if( fileName.lastIndexOf("\\") >= 0 ){
               file = new File( filePath + 
               fileName.substring( fileName.lastIndexOf("\\"))) ;
            }else{
               file = new File( filePath + 
               fileName.substring(fileName.lastIndexOf("\\")+1)) ;
            }
            fi.write( file ) ;
            out.println("Uploaded Filename: " + fileName + "<br>");
         }
      }
      out.println("</body>");
      out.println("</html>");
   }catch(Exception ex) {
       System.out.println(ex);
   }
   }
   public void doGet(HttpServletRequest request, 
                       HttpServletResponse response)
        throws ServletException, java.io.IOException {
        
        throw new ServletException("GET method used with " +
                getClass( ).getName( )+": POST method required.");
   } 
}

Compile and Running Servlet:

Compile above servlet UploadServlet and create required entry in web.xml file as follows.

 
<servlet>
   <servlet-name>UploadServlet</servlet-name>
   <servlet-class>UploadServlet</servlet-class>
</servlet>

<servlet-mapping>
   <servlet-name>UploadServlet</servlet-name>
   <url-pattern>/UploadServlet</url-pattern>
</servlet-mapping>
Now try to upload files using the HTML form which you created above. When you would try http://localhost:8080/UploadFile.htm, it would display following result which would help you uploading any file from your local machine.

 
File Upload: 
Select a file to upload: 
 
 

 
 

If your servelt script works fine, your file should be uploaded in c:\apache-tomcat-5.5.29\webapps\data\ directory.

Servlets - Database Access


This tutorial assumes you have understanding on how JDBC application works. Before starting with database access through a servlet, make sure you have proper JDBC environment setup along with a database.
For more detail on how to access database using JDBC and its environment setup you can go through my JDBC Tutorial.
To start with basic concept, let us create a simple table and create few records in that table as follows:

Create Table

To create the Employees table in TEST database, use the following steps:

Step 1:

Open a Command Prompt and change to the installation directory as follows:

C:\>
C:\>cd Program Files\MySQL\bin
C:\Program Files\MySQL\bin>

Step 2:

Login to database as follows

C:\Program Files\MySQL\bin>mysql -u root -p
Enter password: ********
mysql>

Step 3:

Create the table Employee in TEST database as follows:

mysql> use TEST;
mysql> create table Employees
    (
     id int not null,
     age int not null,
     first varchar (255),
     last varchar (255)
    );
Query OK, 0 rows affected (0.08 sec)
mysql>

Create Data Records

Finally you create few records in Employee table as follows:
mysql> INSERT INTO Employees VALUES (100, 18, 'Zara', 'Ali');
Query OK, 1 row affected (0.05 sec)
 
mysql> INSERT INTO Employees VALUES (101, 25, 'Mahnaz', 'Fatma');
Query OK, 1 row affected (0.00 sec)
 
mysql> INSERT INTO Employees VALUES (102, 30, 'Zaid', 'Khan');
Query OK, 1 row affected (0.00 sec)
 
mysql> INSERT INTO Employees VALUES (103, 28, 'Sumit', 'Mittal');
Query OK, 1 row affected (0.00 sec)
 
mysql>

Accessing a Database:

Here is an example which shows how to access TEST database using Servlet.

// Loading required libraries
import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.sql.*;
 
public class DatabaseAccess extends HttpServlet{
    
  public void doGet(HttpServletRequest request,
                    HttpServletResponse response)
            throws ServletException, IOException
  {
      // JDBC driver name and database URL
      static final String JDBC_DRIVER="com.mysql.jdbc.Driver";  
      static final String DB_URL="jdbc:mysql://localhost/TEST";

      //  Database credentials
      static final String USER = "root";
      static final String PASS = "password";

      // Set response content type
      response.setContentType("text/html");
      PrintWriter out = response.getWriter();
      String title = "Database Result";
      String docType =
        "<!doctype html public \"-//w3c//dtd html 4.0 " +
         "transitional//en\">\n";
         out.println(docType +
         "<html>\n" +
         "<head><title>" + title + "</title></head>\n" +
         "<body bgcolor=\"#f0f0f0\">\n" +
         "<h1 align=\"center\">" + title + "</h1>\n");
      try{
         // Register JDBC driver
         Class.forName("com.mysql.jdbc.Driver");

         // Open a connection
         conn = DriverManager.getConnection(DB_URL,USER,PASS);

         // Execute SQL query
         stmt = conn.createStatement();
         String sql;
         sql = "SELECT id, first, last, age FROM Employees";
         ResultSet rs = stmt.executeQuery(sql);

         // Extract data from result set
         while(rs.next()){
            //Retrieve by column name
            int id  = rs.getInt("id");
            int age = rs.getInt("age");
            String first = rs.getString("first");
            String last = rs.getString("last");

            //Display values
            out.println("ID: " + id + "<br>");
            out.println(", Age: " + age + "<br>");
            out.println(", First: " + first + "<br>");
            out.println(", Last: " + last + "<br>");
         }
         out.println("</body></html>");

         // Clean-up environment
         rs.close();
         stmt.close();
         conn.close();
      }catch(SQLException se){
         //Handle errors for JDBC
         se.printStackTrace();
      }catch(Exception e){
         //Handle errors for Class.forName
         e.printStackTrace();
      }finally{
         //finally block used to close resources
         try{
            if(stmt!=null)
               stmt.close();
         }catch(SQLException se2){
         }// nothing we can do
         try{
            if(conn!=null)
            conn.close();
         }catch(SQLException se){
            se.printStackTrace();
         }//end finally try
      } //end try
   }
} 

Now let us compile above servlet and create following entries in web.xml

....
 <servlet>
     <servlet-name>DatabaseAccess</servlet-name>
     <servlet-class>DatabaseAccess</servlet-class>
 </servlet>
 
 <servlet-mapping>
     <servlet-name>DatabaseAccess</servlet-name>
     <url-pattern>/DatabaseAccess</url-pattern>
 </servlet-mapping>
....

Now call this servlet using URL http://localhost:8080/DatabaseAccess which would display following response:

Database Result

ID: 100, Age: 18, First: Zara, Last: Ali ID: 101, Age: 25, First: Mahnaz, Last: Fatma ID: 102, Age: 30, First: Zaid, Last: Khan ID: 103, Age: 28, First: Sumit, Last: Mittal

Servlets - Session Tracking


HTTP is a "stateless" protocol which means each time a client retrieves a Web page, the client opens a separate connection to the Web server and the server automatically does not keep any record of previous client request.
Still there are following three ways to maintain session between web client and web server:

(1) Cookies:

A webserver can assign a unique session ID as a cookie to each web client and for subsequent requests from the client they can be recognized using the recieved cookie.
This may not be an effective way because many time browser does nots upport a cookie, so I would not recommend to use this procedure to maintain the sessions.

(2) Hidden Form Fields:

A web server can send a hidden HTML form field along with a unique session ID as follows:
<input type="hidden" name="sessionid" value="12345">
This entry means that, when the form is submitted, the specified name and value are automatically included in the GET or POST data. Each time when web browser sends request back, then session_id value can be used to keep the track of different web browsers.
This could be an effective way of keeping track of the session but clicking on a regular (<A HREF...>) hypertext link does not result in a form submission, so hidden form fields also cannot support general session tracking.

(3) URL Rewriting:

You can append some extra data on the end of each URL that identifies the session, and the server can associate that session identifier with data it has stored about that session.
For example, with http://tutorialspoint.com/file.htm;sessionid=12345, the session identifier is attached as sessionid=12345 which can be accessed at the web server to identify the client.
URL rewriting is a better way to maintain sessions and works for the browsers when they don't support cookies but here drawback is that you would have generate every URL dynamically to assign a session ID though page is simple static HTML page.

The HttpSession Object:

Apart from the above mentioned three ways, servlet provides HttpSession Interface which provides a way to identify a user across more than one page request or visit to a Web site and to store information about that user.
The servlet container uses this interface to create a session between an HTTP client and an HTTP server. The session persists for a specified time period, across more than one connection or page request from the user.
You would get HttpSession object by calling the public method getSession() of HttpServletRequest, as below:

HttpSession session = request.getSession();
You need to call request.getSession() before you send any document content to the client. Here is a summary of the important methods available through HttpSession object:

S.N.Method & Description
1public Object getAttribute(String name)
This method returns the object bound with the specified name in this session, or null if no object is bound under the name.
2public Enumeration getAttributeNames()
This method returns an Enumeration of String objects containing the names of all the objects bound to this session.
3public long getCreationTime()
This method returns the time when this session was created, measured in milliseconds since midnight January 1, 1970 GMT.
4public String getId()
This method returns a string containing the unique identifier assigned to this session.
5public long getLastAccessedTime()
This method returns the last time the client sent a request associated with this session, as the number of milliseconds since midnight January 1, 1970 GMT.
6public int getMaxInactiveInterval()
This method returns the maximum time interval, in seconds, that the servlet container will keep this session open between client accesses.
7public void invalidate()
This method invalidates this session and unbinds any objects bound to it.
8public boolean isNew(
This method returns true if the client does not yet know about the session or if the client chooses not to join the session.
9public void removeAttribute(String name)
This method removes the object bound with the specified name from this session.
10public void setAttribute(String name, Object value)
This method binds an object to this session, using the name specified.
11public void setMaxInactiveInterval(int interval)
This method specifies the time, in seconds, between client requests before the servlet container will invalidate this session.

Session Tracking Example:

This example describes how to use the HttpSession object to find out the creation time and the last-accessed time for a session. We would associate a new session with the request if one does not already exist.
// Import required java libraries
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.util.*;
 
// Extend HttpServlet class
public class SessionTrack extends HttpServlet {
 
  public void doGet(HttpServletRequest request,
                    HttpServletResponse response)
            throws ServletException, IOException
  {
      // Create a session object if it is already not  created.
      HttpSession session = request.getSession(true);
      // Get session creation time.
      Date createTime = new Date(session.getCreationTime());
      // Get last access time of this web page.
      Date lastAccessTime = 
                        new Date(session.getLastAccessedTime());

      String title = "Welcome Back to my website";
      Integer visitCount = new Integer(0);
      String visitCountKey = new String("visitCount");
      String userIDKey = new String("userID");
      String userID = new String("ABCD");

      // Check if this is new comer on your web page.
      if (session.isNew()){
         title = "Welcome to my website";
         session.setAttribute(userIDKey, userID);
      } else {
         visitCount = (Integer)session.getAttribute(visitCountKey);
         visitCount = visitCount + 1;
         userID = (String)session.getAttribute(userIDKey);
      }
      session.setAttribute(visitCountKey,  visitCount);

      // Set response content type
      response.setContentType("text/html");
      PrintWriter out = response.getWriter();

      String docType =
      "<!doctype html public \"-//w3c//dtd html 4.0 " +
      "transitional//en\">\n";
      out.println(docType +
                "<html>\n" +
                "<head><title>" + title + "</title></head>\n" +
                "<body bgcolor=\"#f0f0f0\">\n" +
                "<h1 align=\"center\">" + title + "</h1>\n" +
                 "<h2 align=\"center\">Session Infomation</h2>\n" +
                "<table border=\"1\" align=\"center\">\n" +
                "<tr bgcolor=\"#949494\">\n" +
                "  <th>Session info</th><th>value</th></tr>\n" +
                "<tr>\n" +
                "  <td>id</td>\n" +
                "  <td>" + session.getId() + "</td></tr>\n" +
                "<tr>\n" +
                "  <td>Creation Time</td>\n" +
                "  <td>" + createTime + 
                "  </td></tr>\n" +
                "<tr>\n" +
                "  <td>Time of Last Access</td>\n" +
                "  <td>" + lastAccessTime + 
                "  </td></tr>\n" +
                "<tr>\n" +
                "  <td>User ID</td>\n" +
                "  <td>" + userID + 
                "  </td></tr>\n" +
                "<tr>\n" +
                "  <td>Number of visits</td>\n" +
                "  <td>" + visitCount + "</td></tr>\n" +
                "</table>\n" +
                "</body></html>");
  }
}
Compile above servlet SessionTrack and create appropriate entry in web.xml file. Now runninghttp://localhost:8080/SessionTrack would display the following result when you would run for the first time:

Welcome to my website

Session Infomation

Session infovalue
id0AE3EC93FF44E3C525B4351B77ABB2D5
Creation TimeTue Jun 08 17:26:40 GMT+04:00 2010
Time of Last AccessTue Jun 08 17:26:40 GMT+04:00 2010
User IDABCD
Number of visits0
Now try to run the same servlet for second time, it would display following result.

Welcome Back to my website

Session Infomation

info typevalue
id0AE3EC93FF44E3C525B4351B77ABB2D5
Creation TimeTue Jun 08 17:26:40 GMT+04:00 2010
Time of Last AccessTue Jun 08 17:26:40 GMT+04:00 2010
User IDABCD
Number of visits1

Deleting Session Data:

When you are done with a user's session data, you have several options:
  1. Remove a particular attribute: You can call public void removeAttribute(String name)method to delete the value associated with a particular key.
  2. Delete the whole session: You can call public void invalidate() method to discard an entire session.
  3. Setting Session timeout: You can call public void setMaxInactiveInterval(int interval)method to set the timeout for a session individually.
  4. Log the user out: The servers that support servlets 2.4, you can call logout to log the client out of the Web server and invalidate all sessions belonging to all the users.
  5. web.xml Configuration: If you are using Tomcat, apart from the above mentioned methods, you can configure session time out in web.xml file as follows.
  <session-config>
    <session-timeout>15</session-timeout>
  </session-config>

The timeout is expressed as minutes, and overrides the default timeout which is 30 minutes in Tomcat.
The getMaxInactiveInterval( ) method in a servlet returns the timeout period for that session in seconds. So if your session is configured in web.xml for 15 minutes, getMaxInactiveInterval( ) returns 900.

Servlets - Cookies Handling


Cookies are text files stored on the client computer and they are kept for various information tracking purpose. Java Servlets transparently supports HTTP cookies.
There are three steps involved in identifying returning users:
  • Server script sends a set of cookies to the browser. For example name, age, or identification number etc.
  • Browser stores this information on local machine for future use.
  • When next time browser sends any request to web server then it sends those cookies information to the server and server uses that information to identify the user.
This chapter will teach you how to set or reset cookies, how to access them and how to delete them.

The Anatomy of a Cookie:

Cookies are usually set in an HTTP header (although JavaScript can also set a cookie directly on a browser). A servlet that sets a cookie might send headers that look something like this:
HTTP/1.1 200 OK
Date: Fri, 04 Feb 2000 21:03:38 GMT
Server: Apache/1.3.9 (UNIX) PHP/4.0b3
Set-Cookie: name=xyz; expires=Friday, 04-Feb-07 22:03:38 GMT; 
                 path=/; domain=tutorialspoint.com
Connection: close
Content-Type: text/html
As you can see, the Set-Cookie header contains a name value pair, a GMT date, a path and a domain. The name and value will be URL encoded. The expires field is an instruction to the browser to "forget" the cookie after the given time and date.
If the browser is configured to store cookies, it will then keep this information until the expiry date. If the user points the browser at any page that matches the path and domain of the cookie, it will resend the cookie to the server. The browser's headers might look something like this:

GET / HTTP/1.0
Connection: Keep-Alive
User-Agent: Mozilla/4.6 (X11; I; Linux 2.2.6-15apmac ppc)
Host: zink.demon.co.uk:1126
Accept: image/gif, */*
Accept-Encoding: gzip
Accept-Language: en
Accept-Charset: iso-8859-1,*,utf-8
Cookie: name=xyz

A servlet will then have access to the cookie through the request method request.getCookies()which returns an array of Cookie objects.

Servlet Cookies Methods:

Following is the list of useful methods which you can use while manipulating cookies in servlet.

S.N.Method & Description
1public void setDomain(String pattern)
This method sets the domain to which cookie applies, for example tutorialspoint.com.
2public String getDomain()
This method gets the domain to which cookie applies, for example tutorialspoint.com.
3public void setMaxAge(int expiry)
This method sets how much time (in seconds) should elapse before the cookie expires. If you don't set this, the cookie will last only for the current session.
4public int getMaxAge()
This method returns the maximum age of the cookie, specified in seconds, By default, -1 indicating the cookie will persist until browser shutdown.
5public String getName()
This method returns the name of the cookie. The name cannot be changed after creation.
6public void setValue(String newValue)
This method sets the value associated with the cookie.
7public String getValue()
This method gets the value associated with the cookie.
8public void setPath(String uri)
This method sets the path to which this cookie applies. If you don't specify a path, the cookie is returned for all URLs in the same directory as the current page as well as all subdirectories.
9public String getPath()
This method gets the path to which this cookie applies.
10public void setSecure(boolean flag)
This method sets the boolean value indicating whether the cookie should only be sent over encrypted (i.e. SSL) connections.
11public void setComment(String purpose)
This method specifies a comment that describes a cookie's purpose. The comment is useful if the browser presents the cookie to the user.
12public String getComment()
This method returns the comment describing the purpose of this cookie, or null if the cookie has no comment.

Setting Cookies with Servlet:

Setting cookies with servlet involves three steps:
(1) Creating a Cookie object: You call the Cookie constructor with a cookie name and a cookie value, both of which are strings.

Cookie cookie = new Cookie("key","value");
Keep in mind, neither the name nor the value should contain white space or any of the following characters:

[ ] ( ) = , " / ? @ : ;

(2) Setting the maximum age: You use setMaxAge to specify how long (in seconds) the cookie should be valid. Following would set up a cookie for 24 hours.

cookie.setMaxAge(60*60*24); 

(3) Sending the Cookie into the HTTP response headers: You use response.addCookieto add cookies in the HTTP response header as follows:

response.addCookie(cookie);

Example:

Let us modify our Form Example to set the cookies for first and last name.

// Import required java libraries
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
 
// Extend HttpServlet class
public class HelloForm extends HttpServlet {
 
  public void doGet(HttpServletRequest request,
                    HttpServletResponse response)
            throws ServletException, IOException
  {
      // Create cookies for first and last names.      
      Cookie firstName = new Cookie("first_name",
                      request.getParameter("first_name"));
      Cookie lastName = new Cookie("last_name",
                      request.getParameter("last_name"));

      // Set expiry date after 24 Hrs for both the cookies.
      firstName.setMaxAge(60*60*24); 
      lastName.setMaxAge(60*60*24); 

      // Add both the cookies in the response header.
      response.addCookie( firstName );
      response.addCookie( lastName );

      // Set response content type
      response.setContentType("text/html");
 
      PrintWriter out = response.getWriter();
      String title = "Setting Cookies Example";
      String docType =
      "<!doctype html public \"-//w3c//dtd html 4.0 " +
      "transitional//en\">\n";
      out.println(docType +
                "<html>\n" +
                "<head><title>" + title + "</title></head>\n" +
                "<body bgcolor=\"#f0f0f0\">\n" +
                "<h1 align=\"center\">" + title + "</h1>\n" +
                "<ul>\n" +
                "  <li><b>First Name</b>: "
                + request.getParameter("first_name") + "\n" +
                "  <li><b>Last Name</b>: "
                + request.getParameter("last_name") + "\n" +
                "</ul>\n" +
                "</body></html>");
  }
}

Compile above servlet HelloForm and create appropriate entry in web.xml file and finally try following HTML page to call servlet.

 
<html>
<body>
<form action="HelloForm" method="GET">
First Name: <input type="text" name="first_name">
<br />
Last Name: <input type="text" name="last_name" />
<input type="submit" value="Submit" />
</form>
</body>
</html>

Keep above HTML content in a file Hello.htm and put it in <Tomcat-installation-directory>/webapps/ROOT directory. When you would access http://localhost:8080/Hello.htm, here is the actual output of the above form.
First Name: 
Last Name:  
Try to enter First Name and Last Name and then click submit button. This would display first name and last name on your screen and same time it would set two cookies firstName and lastName which would be passed back to the server when next time you would press Submit button.
Next section would explain you how you would access these cookies back in your web application.

Reading Cookies with Servlet:

To read cookies, you need to create an array of javax.servlet.http.Cookie objects by calling thegetCookies( ) method of HttpServletRequest. Then cycle through the array, and use getName() and getValue() methods to access each cookie and associated value.

Example:

Let us read cookies which we have set in previous example:
// Import required java libraries
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
 
// Extend HttpServlet class
public class ReadCookies extends HttpServlet {
 
  public void doGet(HttpServletRequest request,
                    HttpServletResponse response)
            throws ServletException, IOException
  {
      Cookie cookie = null;
	  Cookie[] cookies = null;
      // Get an array of Cookies associated with this domain
      cookies = request.getCookies();
      
	  // Set response content type
      response.setContentType("text/html");
 
      PrintWriter out = response.getWriter();
      String title = "Reading Cookies Example";
      String docType =
      "<!doctype html public \"-//w3c//dtd html 4.0 " +
      "transitional//en\">\n";
      out.println(docType +
                "<html>\n" +
                "<head><title>" + title + "</title></head>\n" +
                "<body bgcolor=\"#f0f0f0\">\n" );
      if( cookies != null ){
         out.println("<h2> Found Cookies Name and Value</h2>");
         for (int i = 0; i < cookies.length; i++){
            cookie = cookies[i];
            out.print("Name : " + cookie.getName( ) + ",  ");
            out.print("Value: " + cookie.getValue( )+" <br/>");
         }
      }else{
          out.println(
            "<h2>No cookies founds</h2>");
      }
      out.println("</body>");
      out.println("</html>");
   }
}

Compile above servlet ReadCookies and create appropriate entry in web.xml file. If you would have set first_name cookie as "John" and last_name cookie as "Player" then runninghttp://localhost:8080/ReadCookies would display the following result:

Found Cookies Name and Value

Name : first_name, Value: John
Name : last_name, Value: Player

Delete Cookies with Servlet:

To delete cookies is very simple. If you want to delete a cookie then you simply need to follow up following three steps:
  1. Read an already exsiting cookie and store it in Cookie object.
  2. Set cookie age as zero using setMaxAge() method to delete an existing cookie.
  3. Add this cookie back into response header.

Example:

Following example would delete and existing cookie named "first_name" and when you would run ReadCookies servlet next time it would return null value for first_name.
// Import required java libraries
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
 
// Extend HttpServlet class
public class DeleteCookies extends HttpServlet {
 
  public void doGet(HttpServletRequest request,
                    HttpServletResponse response)
            throws ServletException, IOException
  {
      Cookie cookie = null;
	  Cookie[] cookies = null;
      // Get an array of Cookies associated with this domain
      cookies = request.getCookies();
      
	  // Set response content type
      response.setContentType("text/html");
 
      PrintWriter out = response.getWriter();
      String title = "Delete Cookies Example";
      String docType =
      "<!doctype html public \"-//w3c//dtd html 4.0 " +
      "transitional//en\">\n";
      out.println(docType +
                "<html>\n" +
                "<head><title>" + title + "</title></head>\n" +
                "<body bgcolor=\"#f0f0f0\">\n" );
       if( cookies != null ){
         out.println("<h2> Cookies Name and Value</h2>");
         for (int i = 0; i < cookies.length; i++){
            cookie = cookies[i];
            if((cookie.getName( )).compareTo("first_name") == 0 ){
                 cookie.setMaxAge(0);
                 response.addCookie(cookie);
                 out.print("Deleted cookie : " + 
                              cookie.getName( ) + "<br/>");
            }
            out.print("Name : " + cookie.getName( ) + ",  ");
            out.print("Value: " + cookie.getValue( )+" <br/>");
         }
      }else{
          out.println(
            "<h2>No cookies founds</h2>");
      }
      out.println("</body>");
      out.println("</html>");
   }
}

Compile above servlet DeleteCookies and create appropriate entry in web.xml file. Now running http://localhost:8080/DeleteCookies would display the following result:

Cookies Name and Value

Deleted cookie : first_name
Name : first_name, Value: John
Name : last_name, Value: Player

Now try to run http://localhost:8080/ReadCookies and it would display only one cookie as follows:

Found Cookies Name and Value

Name : last_name, Value: Player
You can delete your cookies in Internet Explorer manually. Start at the Tools menu and select Internet Options. To delete all cookies, press Delete Cookies.

Servlets - Exception Handling


When a servlet throws an exception, the web container searches the configurations in web.xmlthat use the exception-type element for a match with the thrown exception type.
You would have to use the error-page element in web.xml to specify the invocation of servlets in response to certain exceptions or HTTP status codes.

web.xml Configuration:

Consider, you have an ErrorHandler servelt which would be called whenever there is any defined exception or error. Following would be the entry created in web.xml.
<!-- servlet definition -->
<servlet>
        <servlet-name>ErrorHandler</servlet-name>
        <servlet-class>ErrorHandler</servlet-class>
</servlet>
<!-- servlet mappings -->
<servlet-mapping>
        <servlet-name>ErrorHandler</servlet-name>
        <url-pattern>/ErrorHandler</url-pattern>
</servlet-mapping>

<!-- error-code related error pages -->
<error-page>
    <error-code>404</error-code>
    <location>/ErrorHandler</location>
</error-page>
<error-page>
    <error-code>403</error-code>
    <location>/ErrorHandler</location>
</error-page>

<!-- exception-type related error pages -->
<error-page>
    <exception-type>
          javax.servlet.ServletException
    </exception-type >
    <location>/ErrorHandler</location>
</error-page>

<error-page>
    <exception-type>java.io.IOException</exception-type >
    <location>/ErrorHandler</location>
</error-page>

If you want to have a generic Error Handler for all the exceptions then you should define following error-page instead of defining separate error-page elements for every exception:

<error-page>
    <exception-type>java.lang.Throwable</exception-type >
    <location>/ErrorHandler</location>
</error-page>

Following are the points to be noted about above web.xml for Exception Handling:
  • The servelt ErrorHandler is defined in usual way as any other servlet and configured in web.xml.
  • If there is any error with status code either 404 ( Not Found) or 403 ( Forbidden ), then ErrorHandler servlet would be called.
  • If the web application throws either ServletException or IOException, then the web container invokes the /ErrorHandler servlet.
  • You can define different Error Handlers to handle different type of errors or exceptions. Above example is very much generic and hope it serve the purpose to explain you the basic concept.

Request Attributes - Errors/Exceptions:

Following is the list of request attributes that an error-handling servlet can access to analyse the nature of error/exception.
S.N.Attribute & Description
1javax.servlet.error.status_code
This attribute give status code which can be stored and analysed after storing in a java.lang.Integer data type.
2javax.servlet.error.exception_type
This attribute gives information about exception type which can be stored and analysed after storing in a java.lang.Class data type.
3javax.servlet.error.message
This attribute gives information exact error message which can be stored and analysed after storing in a java.lang.String data type.
4javax.servlet.error.request_uri
This attribute gives information about URL calling the servlet and it can be stored and analysed after storing in a java.lang.String data type.
5javax.servlet.error.exception
This attribute gives information the exception raised which can be stored and analysed after storing in a java.lang.Throwable data type.
6javax.servlet.error.servlet_name
This attribute gives servlet name which can be stored and analysed after storing in a java.lang.String data type.

Error Handler Servlet Example:

Following is the Servlet Example that would be used as Error Handler in case of any error or exception occurs with your any of the servlet defined.
This example would give you basic understanding of Exception Handling in Servlet, but you can write more sophisticated filter applications using the same concept:
// Import required java libraries
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.util.*;

// Extend HttpServlet class
public class ErrorHandler extends HttpServlet {
 
  // Method to handle GET method request.
  public void doGet(HttpServletRequest request,
                    HttpServletResponse response)
            throws ServletException, IOException
  {
      // Analyze the servlet exception       
      Throwable throwable = (Throwable)
      request.getAttribute("javax.servlet.error.exception");
      Integer statusCode = (Integer)
      request.getAttribute("javax.servlet.error.status_code");
      String servletName = (String)
      request.getAttribute("javax.servlet.error.servlet_name");
      if (servletName == null){
         servletName = "Unknown";
      }
      String requestUri = (String)
      request.getAttribute("javax.servlet.error.request_uri");
      if (requestUri == null){
         requestUri = "Unknown";
      }

      // Set response content type
      response.setContentType("text/html");
 
      PrintWriter out = response.getWriter();
	  String title = "Error/Exception Information";
      String docType =
      "<!doctype html public \"-//w3c//dtd html 4.0 " +
      "transitional//en\">\n";
      out.println(docType +
        "<html>\n" +
        "<head><title>" + title + "</title></head>\n" +
        "<body bgcolor=\"#f0f0f0\">\n");

      if (throwable == null && statusCode == null){
         out.println("<h2>Error information is missing</h2>");
         out.println("Please return to the <a href=\"" + 
           response.encodeURL("http://localhost:8080/") + 
           "\">Home Page</a>.");
      }else if (statusCode != null){
         out.println("The status code : " + statusCode);
      }else{
         out.println("<h2>Error information</h2>");
         out.println("Servlet Name : " + servletName + 
                             "</br></br>");
         out.println("Exception Type : " + 
                             throwable.getClass( ).getName( ) + 
                             "</br></br>");
         out.println("The request URI: " + requestUri + 
                             "<br><br>");
         out.println("The exception message: " + 
                                 throwable.getMessage( ));
      }
      out.println("</body>");
      out.println("</html>");
  }
  // Method to handle POST method request.
  public void doPost(HttpServletRequest request,
                     HttpServletResponse response)
      throws ServletException, IOException {
     doGet(request, response);
  }
}

Compile ErrorHandler.java in usual way and put your class file in <Tomcat-installation-directory>/webapps/ROOT/WEB-INF/classes.
Let us add the following configuration in web.xml to handle exceptions:

<servlet>
        <servlet-name>ErrorHandler</servlet-name>
        <servlet-class>ErrorHandler</servlet-class>
</servlet>
<!-- servlet mappings -->
<servlet-mapping>
        <servlet-name>ErrorHandler</servlet-name>
        <url-pattern>/ErrorHandler</url-pattern>
</servlet-mapping>
<error-page>
    <error-code>404</error-code>
    <location>/ErrorHandler</location>
</error-page>
<error-page>
    <exception-type>java.lang.Throwable</exception-type >
    <location>/ErrorHandler</location>
</error-page>

Now try to use a servlet which raise any exception or type a wrong URL, this would trigger Web Container to call ErrorHandler servlet and display an appropriate message as programmed. For example, if you type a wrong URL then it would display the following result:

The status code : 404

Above code may not work with some web browsers. So try with Mozilla and Safari and it should work.

Servlets - Writing Filters


Servlet Filters are Java classes that can be used in Servlet Programming for the following purposes:
  • To intercept requests from a client before they access a resource at back end.
  • To manipulate responses from server before they are sent back to the client.
There are are various types of filters suggested by the specifications:
  • Authentication Filters.
  • Data compression Filters
  • Encryption Filters .
  • Filters that trigger resource access events.
  • Image Conversion Filters .
  • Logging and Auditing Filters.
  • MIME-TYPE Chain Filters.
  • Tokenizing Filters .
  • XSL/T Filters That Transform XML Content.
Filters are deployed in the deployment descriptor file web.xml and then map to either servlet names or URL patterns in your application's deployment descriptor.
When the web container starts up your web application, it creates an instance of each filter that you have declared in the deployment descriptor. The filters execute in the order that they are declared in the deployment descriptor.

Servlet Filter Methods:

A filter is simply a Java class that implements the javax.servlet.Filter interface. The javax.servlet.Filter interface defines three methods:
S.N.Method & Description
1public void doFilter (ServletRequest, ServletResponse, FilterChain)
This method is called by the container each time a request/response pair is passed through the chain due to a client request for a resource at the end of the chain.
2public void init(FilterConfig filterConfig)
This method is called by the web container to indicate to a filter that it is being placed into service.
3public void destroy()
This method is called by the web container to indicate to a filter that it is being taken out of service.

Servlet Filter Example:

Following is the Servlet Filter Example that would print the clients IP address and current date time. This example would give you basic understanding of Servlet Filter, but you can write more sophisticated filter applications using the same concept:
// Import required java libraries
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.util.*;

// Implements Filter class
public class LogFilter implements Filter  {
   public void  init(FilterConfig config) 
                         throws ServletException{
      // Get init parameter 
      String testParam = config.getInitParameter("test-param"); 

      //Print the init parameter 
      System.out.println("Test Param: " + testParam); 
   }
   public void  doFilter(ServletRequest request, 
                 ServletResponse response,
                 FilterChain chain) 
                 throws java.io.IOException, ServletException {

      // Get the IP address of client machine.   
      String ipAddress = request.getRemoteAddr();

      // Log the IP address and current timestamp.
      System.out.println("IP "+ ipAddress + ", Time "
                                       + new Date().toString());

      // Pass request back down the filter chain
      chain.doFilter(request,response);
   }
   public void destroy( ){
      /* Called before the Filter instance is removed 
      from service by the web container*/
   }
}

Compile LogFilter.java in usual way and put your class file in <Tomcat-installation-directory>/webapps/ROOT/WEB-INF/classes.

Servlet Filter Mapping in Web.xml:

Filters are defined and then mapped to a URL or Servlet, in much the same way as Servlet is defined and then mapped to a URL pattern. Create the following entry for filter tag in the deployment descriptor file web.xml
<filter>
   <filter-name>LogFilter</filter-name>
   <filter-class>LogFilter</filter-class>
   <init-param>
	  <param-name>test-param</param-name>
	  <param-value>Initialization Paramter</param-value>
   </init-param>
</filter>
<filter-mapping>
   <filter-name>LogFilter</filter-name>
   <url-pattern>/*</url-pattern>
</filter-mapping>
The above filter would apply to all the servlets because we specified /* in our configuration. You can specicy a particular servlet path if you want to apply filter on few servlets only.
Now try to call any servlet in usual way and you would see generated log in your web server log. You can use Log4J logger to log above log in a separate file.

Using Multiple Filters:

Your web application may define several different filters with a specific purpose. Consider, you define two filters AuthenFilter and LogFilter. Rest of the process would remain as explained above except you need to create a different mapping as mentioned below:
<filter>
   <filter-name>LogFilter</filter-name>
   <filter-class>LogFilter</filter-class>
   <init-param>
	  <param-name>test-param</param-name>
	  <param-value>Initialization Paramter</param-value>
   </init-param>
</filter>

<filter>
   <filter-name>AuthenFilter</filter-name>
   <filter-class>AuthenFilter</filter-class>
   <init-param>
	  <param-name>test-param</param-name>
	  <param-value>Initialization Paramter</param-value>
   </init-param>
</filter>

<filter-mapping>
   <filter-name>LogFilter</filter-name>
   <url-pattern>/*</url-pattern>
</filter-mapping>

<filter-mapping>
   <filter-name>AuthenFilter</filter-name>
   <url-pattern>/*</url-pattern>
</filter-mapping>

Filters Application Order:

The order of filter-mapping elements in web.xml determines the order in which the web container applies the filter to the servlet. To reverse the order of the filter, you just need to reverse the filter-mapping elements in the web.xml file.
For example, above example would apply LogFilter first and then it would apply AuthenFilter to any servlet but the following example would reverse the order:
<filter-mapping>
   <filter-name>AuthenFilter</filter-name>
   <url-pattern>/*</url-pattern>
</filter-mapping>

<filter-mapping>
   <filter-name>LogFilter</filter-name>
   <url-pattern>/*</url-pattern>
</filter-mapping>