20 Cookies and Sessions
Pravin Jain
Introduction
In an earlier module, we have seen about HTTP specific APIs. we have started looking at javax.servet.http package. We saw the two interfaces, .HTTPServletRequest and HTTPServletResponse. We have also seen the HTTPServlet class.
In this module we will be looking at cookies and sessions. Sessions also many times do depend on cookies and the purpose of session is to be able to track the user.
Let’s start understanding what a cookie really is and how a session is managed in a container. The management of a session in a container is mainly for the purpose of tracking a particular user in a stateless protocol like HTTP. We understand HTTP being a stateless protocol.
What is a Cookie?
Cookie is some kind of a key value pair or some kind of parameter which is stored on the client side. Cookie is managed in the client, but who is responsible for creating those key value pair? It is the server. Where are the cookies used?
A very simple example
In a website, as you login, it would ask REMEMBER ME? It’s basically an auto login. How an auto login is done? I should get logged in automatically if I hit this particular URL(server).
I should not enter username and password every time. Don’t show me the login screen when I go to the index page. Straight away just log me in, So how is that managed?
For managing that, when it says remember me, oh who is remembering whom? Is it the server who is remembering the client? No the server does not have the capability to remember each and every client.
let’s see what the server does for this? It’s basically done by cookies.
When you submit the request and you tick the check-box saying remember me, the request which has gone, it has sent a parameter saying that remember me is checked. When this request is received by the server. What the server does is, that while giving back response is adding some Http header, which is an indication to the client that you please remember this cookie for me. It is sending a cookie to the client, please remember this cookie for me, from now onwards whenever you connect to me, you need to send this as a token.
The browser (Http client) is making requests to different different servers. The client is supposed to remember various parameters which have been set on it by different servers. It maintains a kind of cookie database. which has to be managed server wise.
Certain cookies may be specific to a URL. for a particular URL there is a particular cookie. It will go as part of a request header to the server. Before the cookie goes there, it needs to be set up on the client.
Setting up cookie on the client will be done by the server. whenever any request is being created and formatted on the client side to be sent to the server, it will do a check of the cookie database. Do I have a cookie for this particular server. If there is a cookie, a header is put in the request and that’s how cookies are being sent from client to server.
This will be helpful for auto-login as the browser remembers the username and password as cookies. So that there is no need for the server to send the login page every time, and the user can be authenticated from the cookies being sent from client to server.
What is a Session?
Let’s talk about session.
You might have seen a shopping cart application. In a shopping cart what is done? When user ticks an item to put it into the cart, that is one request sent to the server. Next time when he ticks another item, another request is sent to the server, but how does the server know that this request is coming from the same client?
There is one more product to be added in that cart. How does it manage various carts for all the users?
The server has to keep track of users. We understand HTTP is stateless. There was one request sent from the client and then that got disconnected. Disconnected in the sense that the request was over, and the response was given back to the client. Now he moves to the other part of application and says, oh, I need to add another item to the cart.
How does the server the identify which cart? Which user? Is some cart created for the user or not?
For this there has to be a mechanism of tracking each user on the server side. This tracking involves the use of sessions.
We have got something called HTTPSession. This interface is available in javax.servlet.http package.
Tracking a Client?
How a client is being tracked? But before that, what is the requirement here?
The requirement here from server’s point of view. The server would like to be able to track each client. We have the HTTP protocol where each request is a new request. You have to identify who it is?
It’s not that every client needs to be tracked. We might start tracking a client once he has done login. You many times get user-specific information displayed on all subsequent pages after a successful login. You see your name being displayed. How is all that happening?
To start tracking user is the responsibility of the container. It is the container who is tracking the client. This is the responsibility of the container and not the servlet. Servlets are just components which are managed by the container.
So let’s see what all happens within the container now?
It may be a requirement that a particular client needs to be tracked, we can see how exactly a container would know that a client needs to be tracked. If a client needs to be tracked..the indication to the container has to be given by the application. So the application components can say, ok, I would like the current client to be tracked. Once it has been identified by the container that this client needs to be tracked, what the client does for him?
Think of a server creating a basket(object of HTTPSession) in which we can put various things. There is a basket which has been identified for this particular client which is nothing but our HTTPSession object. If a client needs to be tracked, a HTTPSession object would be created for him. This HTTPSession object is identified with the help of session ID. So there is a session ID which is generated for the client who is to be tracked.
The things which happen on a container are
a) Generation of Session ID.
b) Creation of HTTPSession Object.
Subsequent response which goes from the server now would have a mechanism of telling the client that this is your sessionID.
In all your subsequent transactions from now onwards, You need to be sending this back to me. This can be managed through a cookie.
Setting up a SessionID value on a client can be done by using a cookie also. Cookie is one of the mechanisms which can be used for session tracking. Whenever any request comes from the client, what would the container do?
Do I have any sessionID in the request? If I have I can identify the HTTPSession object for that client. Irrespective of what the application is doing…one of the things done by the container here is to put a time stamp on HTTPSession object that last time when I have received a request from this client is so and so…so last request date-time is being set on the HTTPSession object, this is done because at any point of time a browser can be switched or it can go off. So there is no point in still maintaining the previous HTTPSession for that client.(because that user is gone).
So there has to be some mechanism for throwing away those objects of HTTPSession
In order to be able to manage the HTTPSession objects and not overdoing it, we should have the mechanism of throwing away the unwanted HTTPSession objects. For that there would be a time-out mechanism. So each HTTPSession according to the requirement of the application, would have a max inactive interval. If I do not have any request coming from the client which matches this particular sessionID.
Servlet has this API where it can interact with the container and find out about the session, oh for this current user give me his basket, I want to put something there. The container updates the HttpSession object with the last-request time, every time it receives a request from that particular client. So that it can throw away the unwanted HTTPSession objects.
There is a mechanism in the container which keeps on checking the HTTPSession objects, is there an object whose difference between the current time and the last request time is greater than the max inactive interval? If so I know this can be thrown away.
This is how the container manages and tracks users.
How does the container know, when should it start tracking a particular client? That has to be something which is initiated from the application component, mainly a servlet. A servlet would from within the service method, when it gets the request object.
In the HTTPServletRequest, we have this method called getSession()
This has a boolean parameter which is create-if-necessary. The idea here is, if I say getSession() and if I put the value false, I am asking the container, are you tracking this client(client whose request is received)? If you are tracking him, give me the corresponding HTTPSession object or you can give me a null here.
In case you pass true, it means for this particular client from where the request has arrived, Do you already have a session object? If you have, you can give that to me? If you don’t have then I would like you to start tracking him from now onwards.
I had mentioned in the last module, we have the ServletRequest and ServletContext. .Both of these interfaces having those 4 set of methods where object sharing can be done. Those same 4 methods are also available in HTTPSession.
HttpSession is basically a basket where you can manage objects. Methods,
void setAttribute(String name, Object value)
Object getAttibute(String name) Enumeration<String> getAttributeNames() void removeAttribute(String name) are available for the HTTPSession as well.
So what is there in HTTPSession?
a) last requested date time.
b) max inactive interval
c) methods for managing attributes
d) sessionID
The getSession() method is overloaded., so if we don’t pass a boolean value then by default it is considered true. So you may not be specifying the boolean value. Now you use getSession(true), how would you know whether it’s a new session object or the client was already being tracked and then you have got the object for it. You can know this by the method isNew() in HTTPSession We have the appropriate methods for setting and getting the timeout values in the HTTPSession. You can decide the timeout value as per the need of the application. There are few methods in the HTTPServletRequest which are related to the session
Session tracking is normally done using cookies. In case cookies are not available, it might be done through URL-rewriting also. So we have a mechanism in the HTTPServletRequest, a method called isRequestedURLFromCookie(),which returns a boolean value. By this you can know whether this client is being tracked by using a cookie or not. IsRequestedSessionFromURL(), these methods let us know how client is being tracked? whether tracked by cookie or URL-rewriting If it is URL-rewriting it is slightly tedious for the UI part also because UI components wherever they are specifying a submit button..or wherever the request is being sent, the Session ID needs to be added as a part of URL parameter. So there is this additional task for the UI developer.
So tracking through cookie is much simpler. Now we look at the API part related to cookie. We have a separate class called Cookie. We actually have headers, there are headers in the request through which the cookie is made available to the server. Initially it is the server who is setting up the cookie. There are headers as a part of response also, it is through the response headers by which the cookie is set.
The server would use a method to set up a cookie on the client. How does the server do it For that, before the service method is finished, the servlet if wants to set up a cookie in the client, there is method in the HTTPServletResponse…
we have this method called addCookie() where the parameter is the Cookie. Cookie class is in javax.servlet.Http package. Cookie has a simple constructor. You have to use the key value pair..
Cookie has a name and a value. Cookie has an expiry time. A particular cookie should be managed on the client for a specific period of time.
There is method in Cookie by which the setting of expiry time can be done. This is how the server would be able to set Cookie on the client. The servlet would like to check what are the cookies which have arrived from a particular client. For that HTTPServletRequest has method called getCookies() which gives us an array of cookies. If there are no cookies this method does not return an empty array. it would return null. So it’s important to remain careful here so that you don’t get NullPointerException. So it’s good to carry out a check for the null. don’t straight away go for writing loop here.
you can view video on Cookies and Sessions |
Suggested Reading:
- Core Servlets and Java Server Pages Volume 2 by Marty Hall & Larry Brown, Second Edition, Pearson Education.
- Inside Servlets by Dustin R Callaway, Pearson Education.
- Java Server Programming for Professionals by Ivan Bayross, Sharanam Shah, Cynhthia Bayross and Vaishali Shah Shroff Publishers and Distributros.
- http://download.oracle.com/otndocs/jcp/servlet-3.0-fr-oth-JSpec/