11 - Session Tracking Techniques in Servlets

11.1 Overview

A session is a conversation between the server and a client .We all know that HTTP protocol is a stateless protocol which means no user information is pertained and server considers  every request as a new request.

Why do we need session tracking? Think of the scenario where a series of request and response takes place between same client and a server (for example online shopping system ) so to maintain the conversational state , session tracking is needed.

11.2 Techniques

Basically there are four techniques which can be used to identify a user session.

  1. Cookies
  2. Hidden Fields
  3. URL Rewriting
  4. Session Tracking  API

Cookies , Hidden Fields and URL rewriting involves sending a unique identifier with each request and servlets determines the user session based on the identifier.  Session API uses the other three techniques internally and provides a session tracking in much convenient and stable way.

11.2.1 Cookie

Cookie is a key value pair of information, sent by the server to the browser and then browser sends back this identifier to the server with every request there on.

There are two types of cookies:

Session cookies -  are temporary cookies and are deleted as soon as user closes the browser. The next time user visits the same website, server will treat it as a  new client as cookies are already deleted.

Persistent cookies - remains on hard drive until we delete them or they expire.

If cookie is associated with the client request, server will associate it with corresponding user session otherwise  will create a new unique cookie and send back with response.

Simple code snippet to create a cookie  with name sessionId with a unique value for each client:

Cookie cookie = new Cookie(“sessionID”, “some unique value”);
response.addCookie(cookie);

User can disable cookie support in a browser and in that case server will not be able to identify the user so  this is the major disadvantage of this approach.

11.2.2 Hidden Field

Hidden fields are the input fields which are not displayed on the page but its value is sent to the servlet as other input fields. For example

<input type=”hidden” name=”sessionId” value=”unique value”/>

is a hidden form field which will not displayed to the user but its value will be send to the server and can be retrieved using request.getParameter(“sessionId”)  in servlet.

As we cannot hardcode the value of hidden field created for session tracking purpose, which means we cannot use this approach for static pages like HTML. In short with this approach, HTML pages cannot participate in session tracking with this approach.

Another example will be any get requests like clicking of any link so above two are the major  disadvantages of this approach.

11.2.3 URL Rewriting   

URL Rewriting is the approach in which a session (unique) identifier  gets appended with each request URL so server can identify the user session. For example if we apply URL rewriting on   http://localhost:8080/HelloWorld/SourceServlet , it will become something like

http://localhost:8080/HelloWorld/SourceServlet?jSessionId=XYZ where jSessionId=XYZ is the attached session identifier and value XYZ will be used by server to identify the user session.

There are several advantages of URL rewriting over above discussed approaches like it is browser independent and even if user’s browser does not support cookie or in case  user has disabled cookies, this approach will work.    

 Another advantage is , we need not to submit extra hidden parameter.

As other approaches, this approach also has some disadvantages like we need to regenerate every url to append session identifier and this need to keep track of this identifier until the conversation completes.

11.2.4  Session Tracking API

Servlets provide a convenient and stable session-tracking solution using  the HttpSession API(remember we discussed about HttpSession Object in chapter 4 ?). This interface is built on the  top of  above discussed approaches.

Session tracking in servlet is very simple and it involves following steps

  • Get the associated session object (HttpSession) using request.getSession().
  • To get the specific value out of session object, call getAttribute(String) on the HttpSession object.
  • To store any information in a session call setAttribute(key,object) on a session object.
  • To remove the session data , call removeAttribute(key) to discard a object with a given key.
  • To  invalidate  the session, call invalidate() on session object. This is used to  logout the logged in user.

Let’s discuss Session Tracking API with the help of examples.

11.3 Examples

11.3.1 Write an example to print session Id , session creation time and last accessed time. 

Solution-  HttpSession API provides a method getId() which returns the associated session Id , getCreationTime() to get the session creation time and getLastAccessedTime() to get session last accessed time

getLastAccessedTime() and getCreationTime() returns the time as long data type so to convert it to display format, create a date object passing long value in it.

a. Add entry in web.xml

<servlet>
<servlet-name>SessionInformationServlet</servlet-name>
    <servlet-class>
com.servlet.tutorial.SessionInformationServlet
</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>SessionInformationServlet</servlet-name>
    <url-pattern>/SessionInformationServlet</url-pattern>
</servlet-mapping>

b. Write SessionInformationServlet which will get the session object and displays its attributes

package com.servlet.tutorial;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class SessionInformationServlet extends HttpServlet {
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException
{
        // get session object 
        HttpSession session = request.getSession();
        long creationTime = session.getCreationTime();
        String sessionId = session.getId();
        long lastAccessedTime = session.getLastAccessedTime();
        Date createDate= new Date(creationTime);
        Date lastAccessedDate= new Date(lastAccessedTime);
        StringBuffer buffer = new StringBuffer();
        buffer.append(" <HTML> <HEAD> </HEAD> <BODY>");
        buffer.append("<STRONG> Session ID : </STRONG>" + sessionId);
        buffer.append(" <BR/> ");
        buffer.append("<STRONG> Session Creation Time </STRONG>: " + createDate);
        buffer.append(" <BR/> ");
        buffer.append("<STRONG> Last Accessed Time : </STRONG>" + lastAccessedDate);
        buffer.append(" <BR/> ");
        buffer.append(" </BODY> </HTML> ");
        PrintWriter writer = response.getWriter();
        writer.print( buffer.toString() );
    }
}

Testing

Hit the URL http://localhost:8080/HelloWorld/SessionInformationServlet and it will display session related information (refer below figure).

Hold on for a couple of seconds and refresh the page .This time you will see that session Id  and session creation time will remain same but the last accessed time will be  changed (highlighted below)

Last accessed time is the time when you accessed the session last and since we did wait for some time and accessed the session again, it is modified.

Now close the browser and again hit the same URL (http://localhost:8080/HelloWorld/SessionInformationServlet) and see the difference. This time session Id is different which means new session is created because we closed the browser and opened a new one so server created a new session for the user.

11.3.2 Write an example to demonstrate storing and retrieving of an object from session.

Solution- To demonstrate this scenario, let’s create a servlet which will display the number of times this servlet has been invoked in a particular session. Also a user’s name will be passed as a query parameter.

a. Add entry in web.xml

<servlet>
    <servlet-name>SessionCounterServlet</servlet-name>
    <servlet-class>com.servlet.tutorial.SessionCounterServlet</servlet-class>
    </servlet>
<servlet-mapping>
    <servlet-name>SessionCounterServlet</servlet-name>
    <url-pattern>/SessionCounterServlet</url-pattern>
</servlet-mapping>

b. Write a SessionCounterServlet. This servlet will store the request parameter (username ) in session and will increment the counter variable .

Servlet will verify if counter variable in session is available or not .If it is not available means new user has invoked the servlet and in this case store counter variable with value 1. Later on just increment the existing counter value by 1 and update it in session.

package com.servlet.tutorial;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class SessionCounterServlet extends HttpServlet {
    @Override
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException
    {
        // get session object 
        HttpSession session = request.getSession();
        String username = request.getParameter("username");
        Integer counter = (Integer)session.getAttribute("counter");
        if(counter==null)
        {
            counter=1;
            session.setAttribute("counter",counter);
        }
        else 
        {
            session.setAttribute("counter",counter+1);
        }
        StringBuffer buffer = new StringBuffer();
        buffer.append(" <HTML> <HEAD> </HEAD> <BODY>");
        buffer.append("<STRONG> User name  : </STRONG>" + username);
        buffer.append(" <BR/> ");
        buffer.append("<STRONG> Counter </STRONG>: " + counter);
        buffer.append(" <BR/> ");               
        buffer.append(" </BODY> </HTML> ");
        PrintWriter writer = response.getWriter();
        writer.print( buffer.toString() ); 
    }                                      
}

 Testing

Hit the url http://localhost:8080/HelloWorld/SessionCounterServlet?username=Dummy User

Every time we hit the url again , counter gets incremented

11.3.3 Explain session.invalidate() API with the help of example.

Solution-  session.invalidate() invalidates the session or we can say it kills the corresponding server session. This API is most commonly used when a logged in user logs out. Once the session is invalidated, any other call on that server will throw an error.

  1. create a login.html  to grab username and password of user.
  2. LoginServlet which will store the username in session and will create a link  and clicking on that will invoke LogOut Servlet
  3. LogOutServlet will call session.invalidate() and  will try to access session object fter invalidate which will throw an error.

Add Entry in web.xml

<servlet>
        <servlet-name>LoginServlet</servlet-name>
        <servlet-class>com.servlet.tutorial.LoginServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>LoginServlet</servlet-name>
        <url-pattern>/LoginServlet</url-pattern>
    </servlet-mapping>
    
    <servlet>
        <servlet-name>LogoutServlet</servlet-name>
        <servlet-class>com.servlet.tutorial.LogoutServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>LogoutServlet</servlet-name>
        <url-pattern>/LogoutServlet</url-pattern>
    </servlet-mapping>

Create login.html

<!DOCTYPE html>
<html>
<head>
<title>Login Form</title>
</head>
<body>
<form name="logonform" action="LoginServlet" method="POST">
Username: <input type="text" name="username"/>
<br/>
Password:<input type="password" name="password"/>
<br/>
<input type="submit" value="Submit"/>
</form>
</body>
</html>

Create LoginServlet

package com.servlet.tutorial;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class LoginServlet extends HttpServlet {
@Override
public void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException
    {
        response.setContentType("text/html");
        String username=request.getParameter("username");
        String password=request.getParameter("password");
        HttpSession session = request.getSession();
        session.setAttribute("username", username);
        PrintWriter writer = response.getWriter();
        String message="Username is : "+ username + "<br/> Password is :" + password ;
        message = message + " <br/>To logout click on Logout Link <br/>" ;
        message = message + "<a href=\"LogoutServlet\"> Logout</a>";
        writer.println(message);
    }
}

Create LogoutServlet

package com.servlet.tutorial;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class LogoutServlet extends HttpServlet {
    @Override
    public void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException
    {
        HttpSession session = request.getSession();
        session.invalidate();
        // try to access session object 
        session.getAttribute("username");
    }
}

Testing

Hit the url http://localhost:8080/HelloWorld/lohin.html and enter any username and password

On submit it will invoke the LoginServlet

Clicking  Logout link will invoke doGet() method of LogoutServlet which will invalidate the session and then tries to access the username from session.

By Default link click is a GET request so we implemented doGet() method of LogoutServlet and since it will kill the session, accessing it will throw exception (refer below figure)

11.4 Browser Session vs. Server Session

By default session tracking is based on cookie (session cookie) which is stored in browser memory and not on hard drive. So as soon as browser is closed, that cookie is gone and will not be retrieved again.

Corresponding to this session identifier, a server session is created at server and will be available until it is invalidated or maximum inactive time has been reached. When user closes the browser without logging off, server does not know that browser has  been closed and thus server session remains active till configured maximum inactive time has been reached.

Maximum inactive session time  ( in minutes) can be configured in web.xml like below

<session-config>
    <session-timeout>15</session-timeout>
</session-config>

11.5 Store Attributes in Session object wisely.

At a first glance it looks very convenient to store attributes in session as it is available on any JSP or servlet within the same session. You have to be very careful while storing attributes in session as it can be modified by another JSP or servlet accidently which will result in undesirable behaviour.

Confused? Okay let’s think of a situation where your application has two servlets. Once servlets (FetchBalanceServlet) calls some database system and pulls out bank account balance and stores in a session variable (“accountBalance”) for later use.

You have another servlet “UpdateBalanceServlet” which updates the database with the value  of “accountBalance” session variable.

There is another developer who is also working on your web application and does not know that you have created a session  variable “accountBalance” so he also thought of creating a session variable with same name and stores it value as 0.

Now in any flow if prior the execution of UpdateBalanceServlet, if servlet written by another developer gets executed then it will change the session variable “accountBalance” value ot 0 and then UpdateBalanceServlet will update the account balance in database to 0

So Long Story short “Use Session Variables Wisely”.

Like us on Facebook