Session Management Using Servlet API (Part-3)

techgeek.in's Avatar author of Session Management Using Servlet API (Part-3)
This is an article on Session Management Using Servlet API (Part-3) in Java.
In the previous article we discussed three examples, each of which demonstrates how to track user sessions programmatically, using URL rewriting, cookies, and hidden form fields respectively. Each of these techniques required some unique string to be exchanged between the client and the server, so that the server could recognize the client. However, there are certain complications with all three approaches:

The Java Servlet API, has provisions to look at the session handling The Servlet API provides the following facilities for managing sessions:
  • Management of session lifecycle, including session creation and termination.
  • Management of session state.
The Java Servlet API includes the following interfaces and classes for session management in the javax.servlet.http package:

Interface -------------------------> Description
1. HttpSession --------------------> Provides an abstraction of a session.
2. HttpSessionListener ------------> Handles events associated with session creation and termination (lifecycle events).
3. HttpSessionBindingListener -----> Handles events associated with binding and unbinding state for sessions.
4. HttpSessionActivationListener --> Handles events associated with session activation and passivation (these processes will be explained later).
5. HttpSessionEvent ---------------> Encapsulates lifecycle-specific session events.
6. HttpSessionBindingEvent --------> Encapsulates session binding/unbinding events.

Let's begin our discussion of these interfaces by taking a closer look at the HttpSession interface.

The HttpSession Interface

The HttpSession interface provides core session-management functionality. This interface abstracts a session. The container creates a session when a client first visits a server. Conceptually an HttpSession object is an object that lives for the duration of a client session, and is associated with the request objects.

J2EE web containers use three mechanisms to establish sessions:

Cookies

By default, most containers rely on cookies to establish sessions.

URL rewriting

Web containers support URL rewriting to accommodate clients that do not accept or support cookies. However, in order for web applications to work correctly with URL rewriting, we need to take an extra coding step by calling the encodeURL() method with each URL, and using the return value in the content (instead of the original URL).

SSL based sessions

The Secure Socket Layer (SSL) protocol is used for secure HTTP (HTTPS).

Let's now look at the methods provided by this interface.

The HttpServletRequest interface has the following methods to get instances of HttpSession:

public HttpSession getSession() :-
This method returns the session already associated with this request. However, if there is no session currently associated the request, supplying true to the following variant creates a new Session object and returns it.

public HttpSession getSession(boolean create) :- If the argument is false, and there is no session currently associated with this request, this method returns null.

public Object getAttribute(String name) :- The method returns a named attribute from the session.

public java.util.Enumeration getAttributeNames() :-
The getAttributeNames() method returns an Enumeration of names of all attributes placed into a session.

public long getCreationTime() :- The web container creates a session when a client first accesses the container. The getCreationTime() method returns the time (in milliseconds since midnight January 1, 1970 GMT) at which the session was created. As we shall see later, you can also recreate sessions programmatically.

public String getId() :- The getId() method returns a unique identifier assigned to this session.

public long getLastAccessedTime() :-
The getLastAccessedTime() method returns the time the client last sent a request associated with this session. The time is expressed as milliseconds since midnight January 1, 1970 GMT.

public int getMaxInactiveInterval() :-
The method returns the time the client last sent a request associated with this session. The time is expressed as milliseconds since midnight January 1, 1970 GMT.

public ServletContext getServletContext() :-
The getServletContext() method, unsurprisingly, returns the ServletContext associated with the application that this session belongs to.

public void invalidate() :- The invalidate() method invalidates this session and removes any attributes bound to it.

public boolean isNew() :- The isNew() method returns true if the client does not yet know about this session or if the client chooses not to join the session.

public void removeAttribute(String name) :- The removeAttribute() method removes the named attribute from the session.

public void setAttribute(String name, Object value) :-
The method adds the named attribute to the session. If the named attribute already exists in the session, the method replaces the old attribute value with the new value.

public void setMaxInactiveInterval (int interval) :-
This method sets the maximum allowed time (in seconds) between two consecutive client requests to participate in a session. After expiry of this interval, the container invalidates the session. If a client request arrives after this interval, the request results in a new session.

Let's now study the programming aspects of the session management API via a comprehensive example.

Implementing Session Management



This example builds a web application that allows users to create notes and store them on the server. Each note has a title and associated text, both stored in a database. This example will allow the user to:
  • View the list of notes previously created (using the user's e-mail address to retrieve the list of notes)
  • Create new notes
  • Edit existing notes
  • Change identity and create notes as a different user (identified by another e-mail address)

The following figure shows the flow of events and how we plan to implement the above functionality:



In this figure, the normal arrows indicate the actions by the user, and the dotted arrows indicate the container responses.
There are three components in this application:
  • index.html: This is a welcome page that collects the user's e-mail address.
  • ListNotesServlet: This servlet is responsible for obtaining the list of e-mails from the session. If the session is new, this servlet gets the list of e-mails from the database. This servlet then displays a page containing the list of notes (if any, with hyperlinks), a link to add a note, and another link to change the user. The arrows from this servlet show the possible user actions.
  • EditNoteServlet: This servlet performs two tasks. If the user clicks to edit a note, this servlet retrieves the note from the database and displays it in a form. If the user clicks to add a new note instead, this servlet displays an empty form. When the user submits this form, this servlet stores the note in the database, updates the list of notes in the session, and then forwards the request to the ListNotesServlet. The ListNotesServlet then displays the list of notes.
Therefore, this example relies on the session management API for the following tasks:
  • To track a user entering notes
  • To manage a list of notes
  • To invalidate current sessions and create new sessions

We'll start by creating the database schema.

Database Schema

We will use the MySQL RDBMS for managing the notes persistently. To use this with your webapps we will also need the JDBC driver mm.mysql-2.0.8-bin.jar. The database schema is simple - each note is associated with a note_id and an email address. The actual note data consists of a note_title, note, and the last_modified time.
We Use the following SQL to create the database schema:
Code:
    CREATE DATABASE notepad;
    USE notepad;

    CREATE TABLE NOTES (
      note_id INT AUTO_INCREMENT PRIMARY KEY,
      email CHAR(50) NOT NULL,
      note_title CHAR(80) NOT NULL,
      note LONG VARCHAR,
      last_modified TIMESTAMP NOT NULL
    );
This SQL creates a table called NOTES with the note_id as the primary key. We specify this column as an AUTO_INCREMENT key such that each insert will automatically increment the number. In the above SQL script, we also create two indexes on the email and note_id columns. These are the columns we use to query for NOTES' data.

Welcome Page

We now create the welcome page (index.html) for the notepad web application:
Code:
    <html>
      <head>
        <title>NotePad</title>
        <link rel="stylesheet" type="text/css" href="style/global.css" />
      </head>
      <body>
        <h3>NotePad</h3>
        <form action="/notepad/list" method="GET">
         <p>
           Enter your email address:
           <input type="text" name="email" />
         </p>
         <p>
           <input type="submit" name="submit" value="Enter NotePad">
         </p>
        </form>
      </body>
    </html>
This HTML displays a form for entering the e-mail address of the user. When the user enters the e-mail address, the form sends a GET request to the /notepad/list servlet.

NotePadServlet

This servlet is abstract, and does not directly handle HTTP requests. The purpose of this servlet is to provide the functionality to obtain database connections.
Code:
    import java.sql.*;
    import javax.servlet.http.HttpServlet;

    public abstract class NotePadServlet extends HttpServlet {

     //The getConnection() method returns a database connection:

      protected Connection getConnection() throws NamingException, SQLException {
        Connection connection = null;
        try {
          Class.forName("org.gjt.mm.mysql.Driver").newInstance();
          connection = DriverManager.getConnection("jdbc:mysql://localhost/notepad");
        } catch(ClassNotFoundException cnfe) {
          throw new SQLException("Unable to load the driver: " + cnfe.getMessage());
        }
        return connection;
      }
    }
ListNotesServlet

Let us now create the servlet to retrieve the notes and display them. This servlet extends from NotePadServlet: (read the documentations properly made inside the multiline comment sections.)

Code:
    package sessions;

    import java.util.*;
    import java.io.*;
    import java.sql.*;
    import javax.naming.NamingException;
    import javax.servlet.ServletException;
    import javax.servlet.http.*;

    public class ListNotesServlet extends NotePadServlet {
      protected void doGet(HttpServletRequest request, HttpServletResponse response)
                                              throws ServletException, IOException {

/*This servlet retrieves the parameter email from the incoming request, and uses it to get a list of notes for that user. Note that the form in the welcome page contains an e-mail text field:*/

        String email = request.getParameter("email");

/*The servlet then gets the current user session by calling the getSession() method on the Request object. When the user visits this notepad application for the first time, the container automatically creates a new session for the user. The getSession() method returns the same session to the servlet. When called for the first time, the session will be empty; it does not contain any attributes since we've not yet added any:*/

        HttpSession session = request.getSession();

/*This servlet then checks to see if there is an attribute called email in the session. Say the user revisits the index.html page and enters a new e-mail address to see notes stored under a different e-mail. In this case, the session would contain the old email attribute. The following code checks for this, and if the email is different from that retrieved from the request, it invalidates the current session, and obtains a new session. This step also ensures that a user with a given e-mail address cannot view the notes of another user with a different e-mail address. */

        String currentEmail = (String) session.getAttribute("email");
        if(currentEmail != null) {
          if(!currentEmail.equals(email)) {
            session.invalidate();
            session = request.getSession();
          }
        }

/*The servlet then puts the e-mail address in the session and checks if the list of notes is already available in the session. In this example, the list of notes is stored in a java.util.Map object. This object contains the note_id as the key, and the note_title as the value. The actual note text is retrieved from the database only on demand. This step ensures that we store only the essential information in the HttpSession object, for performance reasons. */

        session.setAttribute("email", email);
        Map noteList = (Map) session.getAttribute("noteList");
        Connection connection = null;
        PreparedStatement statement = null;
        if(noteList == null) {

/*
When the user invokes this servlet for the first time, the noteList will be empty. The servlet then proceeds to retrieve the notes (only note_id and note_title) from the database, and fill this map, as shown below:
*/

          try {
            String sql =
              "SELECT note_id, note_title FROM NOTES WHERE email = ?";
            connection = getConnection();
            statement = connection.prepareStatement(sql);
            statement.setString(1, email);
            ResultSet rs = statement.executeQuery();
            noteList = new HashMap();

            while(rs.next()) {
              noteList.put(new Integer(rs.getInt(1)), rs.getString(2));
            }
          } catch(SQLException sqle) {
            throw new ServletException("SQL Exception", sqle);
          } finally {
            try {
              if(statement != null) {
                statement.close();
              }
            } catch(SQLException ignore) {}
            try {
              if(connection != null) {
                connection.close();
              }
            } catch(SQLException ignore) {}
          }

/*
This code snippet obtains a connection and executes a SQL SELECT statement using the email. It then initializes the noteList map and adds each note_title found into the noteList map using the note_id (converted to an Integer object) as the key. It then adds the noteList to the session under the name noteList as shown below:
*/

          session.setAttribute("noteList", noteList);
        }

/*
The rest of the doGet() method prepares a response. The response includes the list of note titles. Each note is associated with a hyperlink to edit the note. The response also includes a link to add a new note, and another link to change the user. The former link takes the user to the EditNoteServlet, while the latter link takes the user back to the welcome page:
*/

        response.setContentType("text/html");
        PrintWriter writer = response.getWriter();
        writer.println("<html><head>");
        writer.println("<title>NotePad</title>");
        writer.println(
          "<link rel=\"stylesheet\" type=\"text/css\" href=\"style/global.css\" />");
        writer.println("</head><body>");
        writer.println("<h3>Notes</h3>");
        if(noteList.size() == 0) {
          writer.println("<p>You do not have any notes.</p>");
        } else {
          writer.println("<p>Click on the note to edit.</p><ul>");
          Iterator iterator = noteList.keySet().iterator();
          while(iterator.hasNext()) {
            Integer noteId = (Integer) iterator.next();
            String noteTitle = (String) noteList.get(noteId);
            writer.println("<li><a href='/notepad/edit?noteId=" +
            noteId.toString() + "'>" + noteTitle + "</a></li>");
          }
          writer.println("</ul>");
        }
        writer.println("<p><a href='/notepad/edit'>Add a New Note</a></p>");
        writer.println("<p><a href='/notepad/'>Change User</a></p>");
        writer.println("</body></html>");
        writer.close();
      }
/*
Finally, this servlet also implements a doPost() method. As we shall see later, this method is required for the EditNoteServlet to forward to this servlet after saving a note in the database:
*/
     
 protected void doPost(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
        doGet(request, response);
      }
    }
EditNoteServlet

This servlet has two parts - a doGet() method to display a form with the note title and note text (empty for new notes), and a doPost() method to store/update the note in the database. The servlet also extends from the NotePadServlet. This servlet implements two core features. First, given the note_id, it retrieves a note from the database and displays it in a form, and second it stores the note into the database.(read the documentations properly made inside the multiline comment sections.)

Code:
    package sessions;

    import java.util.Map;
    import java.io.*;
    import java.sql.*;
    import javax.naming.NamingException;
    import javax.servlet.*;
    import javax.servlet.http.*;

    public class EditNoteServlet extends NotePadServlet {

/*
The doGet() method of this servlet is responsible for retrieving a note from the database. The same method is also used to display an empty form to enter a new note:
*/

      protected void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {

/*
This method first checks whether there is a noteId in the request. If you examine the ListNotesServlet, the link to add a new note does not include a noteId in the URL, but the links to existing notes include the noteId as a query parameter. This parameter helps the EditNoteServlet to determine if the request is for a new note or for an existing note:
*/

        String noteId = (String) request.getParameter("noteId");
        String note = "";
        String title = "";
        boolean isEdit = false;
        Connection connection = null;
        PreparedStatement statement = null;

        if(noteId != null) {
          try {

/*
If there is no noteId in the request, the servlet generates an HTML form. Otherwise, this servlet retrieves the note from the database:
*/

            String sql = "SELECT note_title, note FROM NOTES WHERE note_id = ?";
            connection = getConnection();
            statement = connection.prepareStatement(sql);
            statement.setInt(1, Integer.parseInt(noteId));
            ResultSet rs = statement.executeQuery();
            rs.next();
            title = rs.getString(1);
            note = rs.getString(2);
            isEdit = true;
          } catch(SQLException sqle) {
            throw new ServletException("SQL Exception", sqle);
          } finally {
            try {
              if(statement != null) {
                statement.close();
              }
            } catch(SQLException ignore) {}
            try {
              if(connection != null) {
                connection.close();
              }
            } catch(SQLException ignore) {}
          }
        }

/*
The above code retrieves the note title and the note text using the note_id. It then stores the results in the local variables title and note respectively.
The following code generates the form containing the note. In the case of a new note, the variables title and note will be empty:
*/

        response.setContentType("text/html");
        PrintWriter writer = response.getWriter();
        writer.println("<html><head>");
        writer.println("<title>NotePad</title>");
        writer.println(
          "<link rel=\"stylesheet\" type=\"text/css\" href=\"style/global.css\" />");
        writer.println("</head><body>");
        writer.println("<h3>Notes</h3>");
        writer.println("<h1>Add/Edit a Note</h1>");
        if(isEdit) {
          writer.println("<form action='/notepad/edit?noteId=" + noteId +
                         "' method='POST'>");
        } else {
          writer.println("<form action='/notepad/edit' method='POST'>");
        }
        writer.println("<p>Title: <input type='text' name='title' size='40' value='" +
                       title + "'></p>");
        writer.println("<p><textarea name='note' cols='50' rows='15'>");
        writer.println(note);
        writer.println("</textarea></p>");
        writer.println("<p><input type='Submit' name='submit'
                       value='Save Note'></p>");
        writer.println("</form></body></html>");
        writer.close();
      }

      protected void doPost(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
/*
The form makes a POST request for saving the note. When the user enters the note and clicks on the Save button, the doPost() method of this servlet gets invoked. The responsibility of the doPost() method is to store the note into the database. Before saving the note, this method retrieves all the necessary information from the Request and Session objects:
*/

        String noteId = (String) request.getParameter("noteId");
        HttpSession session = request.getSession();
        String email = (String) session.getAttribute("email");
        Map noteList = (Map) session.getAttribute("noteList");
        String title = request.getParameter("title");
        String note = request.getParameter("note");
        Connection connection = null;
        PreparedStatement statement = null;
        try {

/*
This servlet uses the noteId parameter in the request to determine if this is a new note or an existing note. If the note is new, it inserts the note in the database:
*/

          if(noteId == null) {
            String sql = "INSERT INTO NOTES (email, note_title, note, last_modified)"
                         + "VALUES(?, ?, ?, ?)";
            connection = getConnection();
            statement = connection.prepareStatement(sql);
            statement.setString(1, email);
            statement.setString(2, title);
            statement.setString(3, note);
            statement.setTimestamp(4, new Timestamp(System.currentTimeMillis()));
            statement.executeUpdate();

            // Retrieve the automatically inserted NOTE_ID
            sql = "SELECT LAST_INSERT_ID()";
            statement = connection.prepareStatement(sql);
            ResultSet rs = statement.executeQuery(sql);
            int id = 0;
            while(rs.next ()) {
              id = rs.getInt(1);
            }
            noteList.put(new Integer(id), title);
          } else {

/*
The note_id is retrieved from the database after executing the INSERT statement. The note_id column is a column automatically incremented by the database whenever a new note is inserted. We therefore must retrieve the inserted value from the database.
If the note already exists, the doPost() method simply updates it:
*/
            String sql = "UPDATE NOTES SET note_title = ?, note = ?, " +
                         "last_modified = ? WHERE note_id = ?";
            connection = getConnection();
            statement = connection.prepareStatement(sql);
            statement.setString(1, title);
            statement.setString(2, note);
            statement.setTimestamp(3, new Timestamp(System.currentTimeMillis()));
            statement.setInt(4, Integer.parseInt(noteId));
            statement.executeUpdate();

            noteList.put(new Integer(noteId), title);
          }
        } catch(SQLException sqle) {
          throw new ServletException("SQL Exception", sqle);
        } finally {
          try {
            if(statement != null) {
              statement.close();
            }
          } catch(SQLException ignore) {}
          try {
            if(connection != null) {
              connection.close();
            }
          } catch(SQLException ignore) {}
        }

/*
Whether we created or updated a note, this method puts the note_id and note_title in the noteList map, so that the ListNotesServlet can display the updated list of notes. After inserting/updating the note, the servlet forwards the request to the ListNotesServlet to display the updated list of notes:
*/
       
 RequestDispatcher rd = request.getRequestDispatcher("/list?email=" + email);
        rd.forward(request, response);
      }
    }
/*
Since the call to the forward() method is performed via the doPost() method, the ListNotesServlet should implement the doPost() method. This is why we implemented the doPost() method in the ListNotesServlet.*/
The next tasks are to write a deployment descriptor, and configure Tomcat to deploy the servlets.

Here's the deployment descriptor for our notepad application:
Code:
    <?xml version="1.0"?>

    <!DOCTYPE web-app
        PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
        "http://java.sun.com/dtd/web-app_2_3.dtd">

    <web-app>

      <servlet>
        <servlet-name>listNotes</servlet-name>
        <servlet-class>ListNotesServlet</servlet-class>
      </servlet>

      <servlet>
        <servlet-name>editNote</servlet-name>
        <servlet-class>EditNoteServlet</servlet-class>
      </servlet>

      <servlet-mapping>
        <servlet-name>listNotes</servlet-name>
        <url-pattern>/list/*</url-pattern>
      </servlet-mapping>

      <servlet-mapping>
        <servlet-name>editNote</servlet-name>
        <url-pattern>/edit/*</url-pattern>
      </servlet-mapping>

    </web-app>
Compiling and Running the Example

The final step is to compile and run the example. You should create a web application called notepad, with following structure:
Code:
    notepad/
            WEB-INF/
                    classes/
                            sessions
                    src/
                        sessions
                    lib/
Place the welcome page in the top level of the web application, and class source files in the src/sessions directory. Add the web.xml file into the top level of the WEB-INF directory as usual. Next, place the mm.mysql-2.0.8-bin.jar file in the lib directory. Then compile the classes and move the class files into the classes/sessions directory.
Restart Tomcat, and navigate to http://localhost:8080/notepad.

If you do this,
  1. you should see the welcome page.
  2. Enter an e-mail address and press the Enter NotePad button. This invokes the ListNotesServlet, retrieves notes (if any), and displays the another page.
  3. Since this is the first time the user entered this web application, there are no notes for this user, and hence the page contains only links to add a new note and to change user. Click on the Add a New Note link. This causes the EditNoteServlet to display a blank form so that we can enter a new note.
  4. Enter any note with a title and some text, and press the Save Note button. This invokes the doPost() method of the EditNoteServlet, that stores the note in the database and updates the noteList with the new noteId and note title. This servlet then forwards the user to the ListNotesServlet that displays the updated note list.
  5. You can continue to add more notes. You may instead change your mind, and enter this application with a new e-mail address. Click on the Change User link to do so, which will then invalidate your current session, obtain a new session, and then display the index.html page to allow you enter a new e-mail address.
NotePad with URL Rewriting

To test if the above NotePad functions without cookies, let's disable cookies in our browser. Check the browser help to get directions to disable all cookies, and restart the browser. As you try entering the web site and continuing to edit a previously created note, you will encounter a NullPointerException displayed in the browser.
What causes this exception? If you look at the source of EditNoteServlet, you will find that the exception was caused due to the variable nodeList being null. The servlet obtains this variable from the session. However, since the browser does not now accept or return cookies, the web container is unable to create and maintain a session. In this case, every time a servlet calls the getSession() method on the Request object, the container returns a new HttpSession object. In our case, the ListNotesServlet creates the list of notes and puts it in the session. However, since the EditNoteServlet is getting a new Session object, there is no way for the EditNoteServlet to retrieve the list of notes.

The Java Servlet API supports URL rewriting to deal with such cases. To enable this, we need to change the two servlets as highlighted below. First, here are the changes we need to make to ListNotesServlet:
Code:
    ...
          } else {
            writer.println("<p>Click on the note to edit.</p><ul>");
            Iterator iterator = noteList.keySet().iterator();
            while(iterator.hasNext()) {
            Integer noteId = (Integer) iterator.next();
            String noteTitle = (String) noteList.get(noteId);
            // Rewrite the URL to the note
            String url = response.encodeURL("/notepad/edit?noteId=" +
                                            noteId.toString());
            writer.println("<li><a href='" + url + "'>" +
                           noteTitle + "</a></li>");
          }
          writer.println("</ul>");
        }
        // Also rewrite the URL for adding a new note
        String url = response.encodeURL("/notepad/edit");
        writer.println("<p><a href='" + url + "'>Add a New Note</a></p>");
        writer.println("<p><a href='/notepad/'>Change User</a></p>");
        writer.println("</body></html>");
        writer.close();
      }
    ...
    }
As you can see, there are two changes. In each of these changes we call the encodeURL() method on the request to "encode" the URL that is being generated. The purpose of this call is to rewrite the URL to include an ID corresponding to the session. Recall from the first example in this chapter that we programmatically rewrote URLs to include randomly generated IDs. The encodeURL() method does a similar task by including a unique ID associated with the current session in the link.

In the original servlet, the URLs it generated were of the form /notepad/edit?noteId=x where x is the note_id. After our modifications, the call to the encodeURL() method appends a token similar to the one we discussed in the first example in this chapter. This method returns a string similar to:


/notepad/edit;jsessionid=C61461E2A200C573A102317140948083?n oteId=x

Note the extra parameter in this URL. The jsessionid is the token the web container uses instead of cookies. The long string following the jsessionid is a session identifier. Note that jsessionid is not an ordinary query parameter; query parameters follow the URL with a question mark, while the jsessionid is separated by a colon. This way, the container ensures that the session identifier is not confused with the query parameters.

Now make similar changes to the EditNoteServlet:
Code:
    ...
        response.setContentType("text/html");
        PrintWriter writer = response.getWriter();
        writer.println("<html><body>");
        writer.println("<h1>Add/Edit a Note</h1>");
        if(isEdit) {
          // Encode the URL to edit the note
          String url = response.encodeURL("/notepad/edit?noteId=" + noteId);
          writer.println("<form action='" + url + "' method='POST'>");
        } else {
          // Encode the URL to add the note
          String url = response.encodeURL("/notepad/edit");
          writer.println("<form action='" + url + "' method='POST'>");
        }
        writer.println("<p>Title: <input type='text' name='title' size='40' value='" +
                       title + "'></p>");
        writer.println("<p><textarea name='note' cols='50' rows='15'>");
        writer.println(note);
        writer.println("</textarea></p>");
        writer.println(
                     "<p><input type='Submit' name='submit' value='Save Note'></p>");
        writer.println("</form></body></html>");
        writer.close();
      }

      protected void doPost(HttpServletRequest request,
                            HttpServletResponse response)
                            throws ServletException, IOException {
    ...
        RequestDispatcher rd =
          request.getRequestDispatcher(response.encodeURL("/list?email=" + email));
        rd.forward(request, response);
      }
    }
When you have made these changes, recompile your servlets, restart Tomcat, and test the application again. This time, you will find the application that the application functions properly, as it did when cookies were enabled.
It is always a good practice to encode all dynamically generated URLs as shown in the above servlets. Although most browsers support cookies, and most users don't disable cookies in their browsers, there are Internet-enabled devices (certain cell phones and hand-held devices) that do not recognize cookies.

[note:- The above article is only for advanced learners. For better understanding of code refer to the documentations made under comments sections inside the code. ]
0
ajit_pimg's Avatar, Join Date: Mar 2010
Go4Expert Member
very fine
0
elizas's Avatar, Join Date: Feb 2010
Light Poster
OleDbDataReader oReader = oCommand.ExecuteReader(CommandBehavior.CloseConnec tion);

The argument "CommandBehavior.CloseConnection" will specify that the connection object will close automatically when we close the Reader object.

The sample code is given below:

OleDbConnection connectionObj = new OleDbConnection(connectionString);
OleDbCommand commandObj = new OleDbCommand();
OleDbDataReader readerObj = null;
commandObj = new OleDbCommand(sqlQuery, connectionObj);
connectionObj.Open();
readerObj = commandObj.ExecuteReader(CommandBehavior.CloseConn ection);


Now when we close the Reader object then the Connection object will close automatically.
0
shabbir's Avatar, Join Date: Jul 2004
Go4Expert Founder
Nominate this article for Article of the month - Apr 2010