Sunday, 12 August 2012

Session Tracking

Why Do We need Session Tracking ?
HTTP is a stateless protocol i.e. every request is considered independent of every other request. But many applications need to maintain a conversational state with the client. A shopping cart is a classical example of such application.

(Suppose a user logs on to the online bookshop, selects some books and adds them to his cart. He enters his billing address and finally submits the order. HTTP cannot track this complete session as it is stateless in nature but user wants that all these should be remembered by server).

Due to this we need some workaround so that server can maintain conversation with client. This is done through session tracking.

There are 3 ways to perform session tracking : Cookies, URL Rewriting and Hidden Fields.

A cookie is a piece of text that a web server can store on a client’s (user) hard disk. Cookies allow the web sites to store information on a client machine and later retrieve it. The pieces of information are stored as name-value pair on the client. Later while reconnecting to the same site, client returns the same name-value pair to server. For example:

1) If we type URL of a Web site into browser, our browser sends a request for that web page. For example, on typing, a request is send to the Amazon’s server.
2) Before sending a request, browser looks for cookie files that amazon has set. If browser finds one or more cookie files related to amazon, it will send it along with the request. If not, no cookie data will be sent with the request.
3) Amazaon web server receives the request and examines the request for cookies. If cookies are received, amazon can use them. If no cookie is received, amazon knows that we have not visited before or the cookies that were previously set got expired.
4) Server creates a new cookie and send to the browser in the header of HTTP Response so that it can be saved on the client machine.

Sending Cookies to Browser
1) Create a Cookie Object
Create a cookie object by calling Cookie constructor, which takes two strings: cookie name and value.

Cookie c = new Cookie (“name”, “value”);
2) Setting Cookie Attributes
Before adding the cookie to response, various characteristics of the cookie can be set. For example, whether a cookie persists on the disk or not. If yes then how long. A cookies by default, lasts only for the current user session and will not be stored on the disk. Using setMaxAge(int lifetime) method indicates how much time (in seconds) should elapse before the cookie expires.

3) Place the Cookie into HTTP response
After making changes to cookie attributes, add this currently created cookie into response.  

Reading Cookies from the Client
1) Reading incoming cookies
To read incoming cookies, get them from the request object of the HttpServeltRequest:
Cookie cookies[] = request.getCookies(); 
This call returns an array of Cookies object corresponding to the name & values that came in the HTTP request header.
2) Looping Cookies Array
Once having an array of cookies, we can iterate over it using getName() & getValue(). These are used to retrieve cookie name and value respectively. 
for(int i=0; i<cookies.length; i++) { 
   Cookie c = cookies[i]; 
   if( c.getName().equals(“someName”) {   
     /* if found, do something with cookie  */

Below figure shows internal working of cookie:

Here is pseudo code for this:

1) On the very first request of a user, server will generate a unique ID. (makeUniqueString is not a pre-defined method). This is done to distinguish one user from another.

      String sID = makeUniqueString();

2) Now server will create a hash table (sessionInfo) for this user. All the data required for maintaining the conversation will be stored in this table for this particular user only.

      Hashtable sessionInfo = new Hashtable();

3) There are two types of data: a) data for maintaining the conversation for each user and b) list of all the users (unique iD for each user) and their respective tables.
In step2, we have already stored (a) type of data. Server also maintains another hash table (globalTable) that stores (b) type of data.

      Hashtable globalTable = findTableStoringSession();
      globalTable.put(sID, sessionInfo);

4) Finally we will create a cookie having the unique ID and send that to the user along with response.

      Cookie sessionCookie = new Cookie("JSESSIONID",sID);

Now with every request after this, client will send this cookie to the server. Server then will extract all the information for this user on the basis of this cookie.
URL Rewriting
This is another way for session tracking. With URL rewriting, the parameter that we want to pass back and forth between the server and client is appended to the URL. This appended information can be retrieved by parsing the URL.
This information can be in the form of: Extra path information, added parameters, or some custom, server-specific URL change. The following URLs have been rewritten to pass the session ID 123:
  • Original –    http://server: port/servlet /rewrite
  • Extra path information –  http://server: port/servlet/rewrite/123
  • Added parameters –  http://server: port/servlet/rewrite?id=123
  • Custom change –   http://server: port/servlet/rewrite;$id$123
Disadvantages of URL rewriting
  • What we bookmark the page and the problem get worse if server is not assigning a unique session id.
  • Every URL on a page, which needs the session information, must be rewritten each time page is served, which can cause computationally expensive and increase communication overhead.
  • Unlike cookies, state information stored in the URL is not persistent
Hidden Form Fields
HTML forms can have an element that looks like the following:

        <INPUT TYPE="HIDDEN" NAME="sessionid" VALUE="123" />

Hidden Forms Fields do not affect the appearance of HTML page. They actually contain the information that is needed to send to the server. Thus, hidden fields can also be used to store information (like sessionid) in order to maintain session.

Java solution for Session Tracking
The Servlet API provides several methods and classes specifically designed to handle session tracking.
Sessions are represented by an HttpSession object.  HttpSession tracking API built on top of URL rewriting and cookies. All cookies and URL rewriting mechanism is hidden and most application server uses cookies but automatically revert to URL rewriting when cookies are unsupported or explicitly disabled.
Below are steps for using HttpSession:
1) Getting the user’s session object
To get the user’s session object, call the getSession() method of HttpServeltRequest that returns the object of HttpSession.

HttpSession sess = request.getSession(true); 
If true is passed to the getSession() method, this method returns the current session associated with this request, or, if the request does not have a session, it creates a new one. In case of passing false, null is returned if the session doesn’t exist.
2) Storing information in a Session 
To store information in Session object (sess), we use setAttribute() method of HttpSession class. Session object works like a HashMap, so it is able to store any java object against key. For example,

sess.setAttribute(“sessionid”, ”123”);

3) Looking up information associated with a Session

To retrieve back the stored information from session object, getAttribute() method of HttpSession class is used. For example,

String sid=(String)sess.getAttribute(“sessionid”);

Note: - getAttribute() method returns Object type, so typecast is required.

4) Terminating a Session

After the amount of time, session gets terminated automatically. We can see its maximum activation time by using getMaxInactiveInterval() method of HttpSession class. However, we can also terminate any existing session manually. For this, we need to call invalidate() method of  HttpSession class.

Encoding URLs sent to Client
Servlet will automatically switch to URL rewriting when cookies are not supported or disabled by the client. When Session Tracking is based on URL rewriting, it requires additional help from the Servlets. For a Servlet to support session tracking via URL rewriting, it has to rewrite (encode) every local URL before sending it to the client. HttpServletResponse provides two methods to perform encoding:
1) String encodeURL(String URL) - This is used for URLs that are embedded in the webpage, that servlet generates. For example,
String URL = ”/servlet/sessiontracker”;
String eURL = response.encodeURL(URL);
out.println(“<A HREF=\” ” + eURL + ”\ ”> …… </A>”); 
2) String encodeRedirectURL(String URL) - This is used for URLs that refers our site is in sendRedirect() call. For example, 
String URL = ”/servlet/sessiontracker”;
String eURL = response.encodeRedirectURL(URL);

No comments:

Post a Comment