This laboratory exercise involves modifying your Counter servletto introduce a second counter. The second counter should keep countof how many times the current user has accessed the servlet, andthis counter will be different for each user.
Level of Difficulty: 4 (moderately difficult)
Estimated time: 20 minutes
Pre-requisites:
The goal of this exercise is to create a servlet that, when invoked,will print out two different counter values:
the original CounterServlet value (total number of times the servlethas been invoked since it was reloaded);
a counter that keeps count of the number of times the current user hasinvoked the servlet in his/her current session.
This requires the use of sessions and session variablesin your servlet.
As you know, HTTP is a stateless protocol. This means that a web server sees each incoming request as beingcompletely independent from all earlier requests.
However many web applications need to keep state information at theserver, so the statelessness of HTTP is a problem.For example, when you access an online banking application, you first log in with your account number and PIN, and then as youclick through various pages on the bank's web site, the applicationrunning on the bank's web server needs to keep track of who you are.
Another example is the ubiquitous shopping cart. As you browse througha product catalog, and add items to your cart, the web applicationneeds to keep track of which items are currently in your cart.
In web application terminology, the word session refers to the interaction between a user and a web application, where the webapplication keeps state information about the user's interactionseven though they span multiple HTTP requests. A session typicallylasts for a single browsing session. If a user closes their browserand re-opens it and goes back to the web application, they will haveto begin a new session. If a user doesn't access the web applicationfor a period of time, their session might time out (whether or not it does is application-dependent).
There are different ways to implement sessions on top of the statelessHTTP protocol. The two typical ways are using cookies andURL rewriting. These will be described in the lecture notes.
Java servlets have built-in support for session management thatsimplifies the task of creating a web application that requiresa session-based interaction with a user.
The abstraction used in Java is the notion of session attributesthat can be stored in a session object. The session objectacts like a container. You can store attributes (name/value pairs)into the session object,and you can retrieve attributes out of the session object.Attributes that are stored in the session object will still keep theirvalue in between successive HTTP requests.Each "attribute value" is, of course, a Java object.
Each attribute stored in the session has a name, and a value.The name is just a String. The value is a Java object.The HttpSession class uses the methodssetAttribute()
and getAttribute
for storing and retrieving attributes in sessions respectively.
Where do you get the session object from in the first place? Fromthe request object. You get the session from the request. If therewas already a session established, then you will have access to allthe variables stored in the session. However if there was not alreadya session established, one will be created automatically (by default),and you will then have access to a blank session object in which youcan store variables.
Now for some code snippets:
Getting hold of a session object (from the request):
HttpSession sess = request.getSession();
Storing an object into the session:
Integer counterVal = new Integer(105); sess.setAttribute("sessionCounter", counterVal);
Retrieving an object from the session:
Integer newCounterVal = (Integer) sess.getAttribute("sessionCounter");
Alternatively, 2 and 3 can be simplified by using auto-boxing and auto-unboxing, introduced in J2SE 5.0 (September 30, 2004) and Java EE 5 (May 11, 2006).So 2 and 3 can be:
int counterVal = 105;/* counterVal is auto-boxed to an Integer object and it is stored in the session */sess.setAttribute("sessionCounter", counterVal);/* * the object returned from the session is casted to Integer then * auto-unboxed to an int value. */int newCounterVal = (Integer) sess.getAttribute("sessionCounter");
With that knowledge, work on modifying your CounterServlet to adda second counter - one that keeps track of the number of accessesa user has made in the current session.
To test, try accessing your servlet from two different browsers(e.g. Firefox and IE on the same machine, or two differentbrowsers on two different machines). Don't just use two differentwindows belonging to the same browser (because different browserwindows still share cookie data, which is used to maintain sessions).
Typically a servlet has to be able to deal with the situationwhen a session does not already exist and has to be initialised.One way to do this is to retrieve an attribute from the session,and if it is null (or if a flag is set to indicate that the session is new), then automatically initialise the attributeand store it in the session. This means that your servlet canboth deal with existing session attributes and automatically set up a new session attribute when needed.
Here is a code sample:
HttpSession sess = request.getSession();Integer sesscounter = (Integer) sess.getAttribute("numAccesses");if (sess.isNew() || sesscounter == null){ sesscounter = new Integer(0); sess.setAttribute("numAccesses", sesscounter);}
The following SessionServletApp servlet illustrates the use of URL rewriting when cookies aren'tsupported in your browser. This servlet also illustrates the use ofServlet API to extract various information related to a session. For this servlet to work, it assumes it is mapped to the URL "session-app".
/* Retrieve the count value from the session */Integer ival = (Integer) session.getAttribute("numAccesses");/* If the counter is not currently contained in the session, one needs to be created: */if (ival == null){ ival = new Integer(1);}else{ ival = new Integer(ival.intValue() + 1);}session.setAttribute("numAccesses", ival);/* Print out how many times the user has hit the current page: */out.println("You have hit this page <b>" + ival + "</b> times.<p>");out.println("Click <a href=" + response.encodeURL("session-app") + ">here</a>");out.println(" to ensure that session tracking is working even " + "if cookies aren't supported.<br>");out.println("<p>");/* Finally, demonstrate some of the more common methods in the HttpSession object surrounding sessions: */out.println("<h3>Request and Session Data:</h3>");out.println("Session ID in Request: " + request.getRequestedSessionId());out.println("<br />Session ID in Request from Cookie: " + request.isRequestedSessionIdFromCookie());out.println("<br />Session ID in Request from URL: " + request.isRequestedSessionIdFromURL());out.println("<br />Valid Session ID: " + request.isRequestedSessionIdValid());out.println("<h3>Session Data:</h3>");out.println("New Session: " + session.isNew());out.println("<br />Session ID: " + session.getId());out.println("<br />Creation Time: " + new java.util.Date(session.getCreationTime()));out.println("<br />Last Accessed Time: " + new java.util.Date(session.getLastAccessedTime()));
Ensure your browser accepts cookies by going to Edit -> Preferences -> Under "History" select "Remember history" (Firefox) or Tools -> Privacy -> Sites (Internet Explorer). If the browser is not allowed to accept cookies, please enable it to accept cookies for this exercise to work. You may need to start the browser again for any changes to take place.
When you access the servlet for the very first time, observe the information returned from the server. Among many things, it should display the session as new. If you press 'Reload' button, the new session should be displayed as false. Also, the request session id from cookie and URL are true and false respectively. This is because you browser is set to accept cookies.
Now, disable the cookies by going to Edit -> Preferences -> Under "History" select "Use custom settings for history" and uncheck "Accept cookies from sites" (Firefox) (see Tools -> Options -> Privacy/ Tools->Privacy-Sites). Restart the browser to take effect of this new change (in Firefox it is sufficient to reload the page). Don't forget to reset to the setting you had before after the exercise.
Access your servlet as before and session should be correctly reported as new. Press Reload button and what you should observe is that the session is still reported as new (same behaviour for multiple reloads). Remember, earlier new session is only reported for the first time you access the page and false for any subsequent accesses (within a session). Even though you didn't use Cookies explicitly, Weblogic uses a temporary cookie to store the current session. Since your browser is set not to accept any cookies (including temporary cookies), sessions do not work correctly.
However, press on 'Click here' link to enable URL writing and watch the URL that appears in the Address/Location bar.You should notice some extra text on the end of the URL indicatingthat URL rewriting is now being used to maintain the session statewhen cookies are disabled. What is also interesting to observe is that the display correctly reports the requested session id is from a URL and not from a Cookie.