Previous | Next
Session Tracking Without CookiesSession tracking is an essential part of most web applications. By nature, the HTTP protocol is connectionless. This means that each time users click on a hyperlink or submit an XHTML form, the browser establishes a new connection to the web server. Once the request is sent and the response is received, the connection between browser and server is broken. This presents a problem for servlet authors. Although the browser and web server do not maintain a persistent connection between page views, applications must maintain state information for each user. Stateful applications make technologies like shopping carts possible, for instance. With each request from the browser, the servlet must reestablish the identity of the user and locate his session information. Servlet Session-Tracking APIThe traditional servlet approach to session tracking utilizes the public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { // retrieve an instance of HttpSession for this user. The "true" parameter // indicates that the object should be created if it does not exist. The first line of the Browser cookies provide the standard method of implementing Figure 8-3. Session trackingCookies are a mixed blessing. Although they make session tracking very easy to implement, this leads to security concerns because people do not want their browsing habits monitored. Therefore, quite a few people set their browsers to disable all cookies. When users disable cookies, servlets must use another technique to enable session tracking. The standard servlet API has a fallback mechanism when cookies are disabled. It reverts to a technique called URL rewriting. If cookies are disabled, the session identifier is appended to the URL. This way, whenever a user clicks on a hyperlink or submits an XHTML form, the session identifier is transmitted along with the request. This cannot happen without some level of developer intervention, however. Imagine a scenario where a servlet is requested, and it returns an XHTML page with the following content: Click on the link to move next: <a href="/shopping/movenext"/>Move Next</a> This causes session tracking to fail, because the session identifier is lost whenever the user clicks on the hyperlink. We really want the HTML to look like this: Click on the link to move next: <a href="/shopping/movenext;jsessionid=0e394s8a576f67b38s7"/>Move Next</a> Now, when the user clicks on the hyperlink, the session identifier ( The value for
String originalURL = "/shopping/moveNext"; String encodedURL = response.encodeURL(originalURL); Now, Session Tracking with Java and XSLTWith XSLT, session tracking is a little harder because the stylesheet generates the URL rather than the servlet. For instance, a stylesheet might contain the following code: <xsl:template match="cart"> Click on the link to move next: <a href="/shopping/movenext"/>Move Next</a> ... </xsl:template> Like before, the
If cookies are enabled, there is no reason to manually implement session tracking. This is easy to check because the Example 8-5. Session-tracking codepublic void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { try { // retrieve current settings from the session HttpSession session = req.getSession(true); Cart cart = (Cart) session.getAttribute("shoppingCart"); if (cart == null) { cart = new Cart( ); session.setAttribute("shoppingCart", cart); } // produce the DOM tree Document doc = CartDOMProducer.createDocument(cart); // prepare the XSLT transformation Transformer trans = StylesheetCache.newTransformer( this.xsltFileName); The critical lines of code are emphasized. The first of these checks to see if the session was not obtained using a cookie: if (!req.isRequestedSessionIdFromCookie( )) { For the very first request, the cookie will not be present because the servlet has not had a chance to create it. For all subsequent requests, the cookie will be missing if the user has disabled cookies in the browser. Under either scenario, the session identifier is obtained from the String sessionID = session.getId( ); The servlet API takes care of generating a random session identifier; you are responsible for preserving this identifier by passing it as a parameter to the stylesheet. This is done as follows: trans.setParameter("global.sessionID", ";jsessionid=" + sessionID); This servlet also takes the liberty of prefixing the session identifier with <a href="/whatever{$global.sessionid}">click here</a> The end result is that if cookies are enabled, the URL will be unaffected. Otherwise, it will be properly encoded to use session tracking. A larger XSLT example follows in Example 8-6. Example 8-6. Session-tracking XSLT stylesheet<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- ********************************************************************* ** global.sessionID : Used for URL-rewriting to implement ** session tracking without cookies. ******************************************************************--> This stylesheet fully illustrates the three key components that make session tracking with XSLT possible. First, the session identifier is passed to the stylesheet as a parameter: <xsl:param name="global.sessionID"/> Next, this session identifier is used for the form action: <form method="post" action="/chap8/shopping{$global.sessionID}"> And finally, it is used for all hyperlinks: <a href="/shopping/movenext{$global.sessionid}?param=value"/>Move Next</a> The http://localhost:8080/shopping/moveNext;jsessionid=298ulkj2348734jkj43?param=value Tracking sessions is essential, and the technique shown in this section works when browser cookies are disabled. You should always test your web applications by disabling all browser cookies to see if every URL is properly encoded with the session identifier. |