IBM®
Skip to main content
    Country/region [select]      Terms of use
 
 
      
     Home      Products      Services & solutions      Support & downloads      My account     

IBM developerWorks : IBM developer solutions : IBM developer solutions articles
developerWorks
Maintaining session data with the WebSphere session manager
131KB e-mail it!
Contents:
Techniques for maintaining session data
httpSession interface
WebSphere Session Manager
A classic example: HitCount
Snoop to the rescue
Conclusion
References
Resources
About the author
Rate this article
Related content:
Subscribe to the developerWorks newsletter
More dW IBM developer solutions resources

Steve Eaton (steaton@us.ibm.com)
IBM
August 2001

This technical article was originally published a previous issue of the IBM DeveloperToolbox Technical Magazine. Subscribe to the IBM developerWorks journal for the latest technical articles on open standards-based technologies that are available to you offline in a printed publication.

A recent film concerns a hero who lost the ability to remember recent events. Every situation he finds himself in is brand new. He has no idea what happened to get him where he is or what he should do next. To make his life manageable, he resorts to taking photos, writing little notes, and even scrawling important messages on himself to remind him later of what has happened and what he needs to do.

Developers of Web applications face much the same problem. Servlets and Java Server Pages (JSP) pages are stateless; that is, they do not know what pages their callers have visited previously or what information they have submitted with earlier requests. What appears to an end user to be a connected series of Web browser pages, displayed while the user refines a search criterion or fills a shopping cart, in reality comprises a sequence of separate programs. Each Hypertext Transfer Protocol (http) request is a new invocation of a servlet, Hypertext Markup Language (html) file, JSP, or other resource, that does not have access to the previous request's data unless the developer provides a way of storing that data on the response to the client and retrieving it from the next request.

This differs from the traditional standalone program that may have displayed a number of windows or prompts while maintaining a single body of data within a single process from start to finish. Moreover, each user who launched the application had a private process space and memory. The developer did not have to worry about concurrent access from multiple users.

This article demonstrates how to manage session data using the Session Manager in the IBM WebSphere Application Server (WAS) Advanced Edition 3.5.3, but the information presented applies to 3.0.x and 4.0 as well.

Techniques for maintaining session data
The HTTP protocol provides three ways of preserving a user's information across multiple requests (a session), regardless of what technology (Common Gateway Interface (cgi) programming or servlets) is used to implement them:

  • Cookies are name and value pairs sent from a Web server to a browser and then returned by the browser when there is a request back to the server. A server program creates a cookie by writing text in the header section of the http response telling the browser what to name the cookie and what value to give it. Browsers can retain cookies across a Web browser session by storing them on the client.
  • Universal Resource Locator (URL) rewriting involves appending data to the end of a URL containing name-value pairs. A server program can create dynamic HTML in which the links the user selects from have data written into them already. This allows session data to be carried along from request to request on the URL.
  • Hidden fields are pre-filled HTML form values that the browser does not display but that are included, along with viewable fields, in the response sent back to the server when the user submits a form request.

Each of these techniques suffer from four major disadvantages:

  • They are designed to handle small amounts of data.
  • They are designed to handle simple, character-string data.
  • They allow end users to view and potentially manipulate session data before it is returned to a server (even hidden form fields can be seen simply by browsing the HTML source).
  • Perhaps worst of all, each of these is merely a mechanism for storing data on the client. All the logic needed to maintain a Web session, such as recognizing when a new session should be started, correctly associating a request with an existing session, ensuring the uniqueness of a session (you don't want to share a user's sensitive information with another), and knowing when and how to terminate a session, needs to be designed and implemented by you as the developer. In other words, you have to take care of session management.

WebSphere's Session Manager component offers a better way.

httpSession interface
The Java servlet specification contains the interface javax.servlet.http.HttpSession that the WebSphere servlet engine supports. HttpSession provides Application Program Interfaces (APIs) that handle many of the details of session access and management. Two important examples of these are:

  • putValue(String name,Object value). Stores an object in an HttpSession under the specified name. Any object can be associated with a session.
  • getValue(String name). Returns the object stored in the HttpSession under the specified name.

How does an HttpSession get created in the first place? By calling the javax.servlet.http.HttpServletRequest getSession() method on the servlet's request object. If a session does not yet exist, this call creates one.

Some of these APIs have been deprecated with the Java Servlet Specification 2.2. The putValue() and getValue() methods, for example, have been replaced by putAttribute() and getAttribute() respectively, although the Java Servlet Specification 2.1 methods are still supported. This article uses the 2.1 method names because they are still used in WebSphere sample code. By using these three APIs in their servlets and JSPs, developers can keep track of session data. So where are the details of session management?

WebSphere Session Manager
Servlet engines running under the WebSphere server contain an object called a Session Manager, as shown in Figure 1. In Version 4.0, the Session Manager interface is built into the properties pane of an application server, rather than being presented as a separate object. Also, you'll see a few more options, which allow you to more finely tune the Session Manager's runtime performance.

Figure 1. WebSphere topology with Session Manager
Fig 1

Let's take a look at some of the important settings you can make to a Session Manager. Most of them are on the Enable tab shown in Figure 2. When you create an application server, you also create a servlet engine object. In turn, the engine automatically creates a Session Manager. The Session Manager allows the WebSphere administrator to dynamically configure and tune the behavior of all HTTP sessions created by servlets within its application server.

Figure 2. Session Manager properties
Fig 2

From an application development perspective, servlet and JSP code do not interact directly with the Session Manager object. Rather, the Session Manager supports the HTTPSession interface, which developers use for session functionality. All the servlet or JSP developer has to do is create the session and put and get data. This allows the application developer to focus on business logic and ensures consistent behavior across all of the servlets called by its servlet engine.

  • Enable Sessions. Selecting yes causes the WebSphere server to keep track of sessions for you, and allows you runtime use of the javax.servlet.http.HttpSession APIs. Selecting no causes a java.lang.RuntimeException to be thrown whenever a servlet attempts to create an HttpSession object. Enabling sessions requires some overhead; if you have a Web application that does not create or gather any session data, you may not want to enable sessions.
  • Enable Cookies. If we are using the HttpSession interface, what do we need cookies for? One key piece of information still has to be stored on the client: an ID that uniquely identifies each session. The Session Manager takes care of creating the session ID, but it has to depend on the client browser to hold it and send it back with subsequent requests. Therefore, for the ID itself, we're back to cookies or URLs. By default, cookies are used. This is a big improvement. Instead of having a note for every important message, our unfortunate hero now only needs one to remind him where the filing cabinet is.
  • Enable URL Rewriting. Instructs the Session Manager to use URL rewriting to store and retrieve the session ID. Unlike cookies, however, using URL rewriting requires additional coding as described in the WebSphere InfoCenter. Another problem with URL rewriting is that it doesn't work if there are any static HTML pages in your application's navigation path. The workaround is to convert any static pages to a jsp file or servlet.

    What happens if you select both Enable Cookies and Enable URL Rewriting? The answer depends on whether a client browser accepts cookies and how a servlet is coded.

    • If a servlet includes logic to encode the session ID as part of the URL, the WebSphere server maintains the session ID as part of the URL, whether or not Enable Cookies is selected and whether or not the requesting browser accepts cookies.
    • If a browser accepts cookies and URL encoding is not used in the servlet, the Enable URL Rewriting setting is effectively ignored; the WebSphere server creates a cookie.
    • If cookies are disabled on the browser, but the responding servlet does not encode the URL, Enable URL Rewriting is also ignored.

    Before you decide to enable URLs, there's a significant disadvantage to consider. If there are any static HTML pages in the Web application's navigation path or servlets or JSPs that do not encode the URL, you will lose the session data.

  • Enable Persistent Sessions. By default, session data is stored in the memory space of the servlet engine. If an application server dies, the data is lost. If this is a concern, select yes to store session data in a database (a WebSphere DataSource you specify on the Persistence properties page) instead of in memory.

    In a development environment, you can use the default DataSource (used by the WebSphere server to store its own information) as your session database. In a production environment, however, work with your database administrator to create a separate database for session management, and create a DataSource to represent the database in the WebSphere console.

    Another reason to enable persistent sessions is if you are implementing a workload management scheme, under which multiple application servers (for example, Java virtual machines with separate memory spaces) may serve the same Web application, each with its memory space. You may even have a Web application served by multiple nodes (physical servers) under the same WebSphere domain. You don't want users who are filling a shopping cart to abruptly start over again because they are bouncing between different clones of the same logical Web application. By enabling persistent sessions and specifying the same data source in each Session Manager, you allow a session to be shared across cloned application servers, possibly on different nodes .

    Session affinity offers another way of dealing with the problem of sessions across multiple servers. Session affinity assures that within the scope of a session, all requests go to the same server. WebSphere Application Server Advanced Edition 3.5.x uses persistent sessions and session affinity together to assure the integrity of a session. It also provides automatic session caching to reduce the performance hit of accessing session data from storage. For detailed information on the WAS's built-in session affinity, consult the WebSphere InfoCenter, section 4.4.1, "Tracking sessions."

    Again, the WebSphere server takes care of the details for you; all you have to do is specify a data source. Keep in mind, however, that by using this feature, you have all the concerns of any database application, such as performance considerations, available connections, and database backup and recovery.

Invalidate Time, located on the Intervals tab, specifies the maximum length of inactivity (no requests) beyond which the WebSphere server will logically kill a session and treat requests as the start of a new session.

A classic example: HitCount
The WebSphere server comes with a simple, yet illustrative, example of using an HttpSession object, the HitCount servlet, as shown in Figure 3. HitCount demonstrates several ways that a servlet can store and retrieve data, including HttpSession.

Figure 3. HitCount servlet output
Fig 3

Selecting the Session state (create if necessary) option, and clicking Increment causes the HitCount to rise. Listing 1 shows the source code from the HitCount servlet.

Listing 1. HTTP session logic from HitCount


HttpSession session = req.getSession(true);
if ( session == null )
      hwcount= "Hit count: Cannot create session as expected!";
else
   {
    integer value = (Integer)session.getValue("hwcount");
    if ( value == null )
            {value = new Integer(1);
               hwcount = "Hit count: 1 (from new session)";
             }
    else
       {value = new Integer(value.intValue() + 1);
          hwcount = "Hit count: " + value +
          " (from existing session)";
        }
    session.putValue("hwcount", value);
}

This code fragment calls a variation of the getSession() method, getSession(boolean). If passed true, it has the same effect as calling getSession(). If a session does not yet exist, one is created.

The logic in HitCount is quite simple, but also quite useful in showing how your application will behave under various scenarios. To get a clear understanding of how sessions work, try the following experiments, starting with the default Session Manager settings:

  1. Launch a browser, and request HitCount. Select Session state (create if necessary) option, and click Increment. Leave that browser up, and launch a new browser. Go to HitCount, and increment again in the new browser. Does it add to the existing count or start a new one? Close all browsers and start over again. Does the count continue, or does it start from zero?
  2. Try the same experiment as in the previous scenario, but use a different browser type. Does it act the same?

    If you tried steps 1 and 2 with the Netscape and Microsoft Internet Explorer Web browsers, you probably noticed that Netscape shared its count across browsers, while Internet Explorer started a new count with each new browser. Remember, the session ID is stored in a cookie. The results demonstrate that Netscape shares its cookies across browser sessions, while Internet Explorer creates separate cookies for each browser.

    This is an important lesson. Even with Session Manager, you are dependent to some extent on the client and how it stores and returns information.

  3. Disable cookies in your browser settings, and try the HitCount session increment option again. What happens now? Note that a new session, with a count of one, gets created each time we hit the servlet. The browser can't stop us from creating a new session and initializing its count to one, but because it won't store the information, it prevents us from retrieving it later. Our poor hero is writing his notes in disappearing ink.
  4. Try selecting Enable URL Rewriting in the Session Manager to address the problem of browsers not accepting cookies. When you test this, you'll see no change in behavior. Remember, URL rewriting requires extra steps in the server code that HitCount does not implement. Again, someone is sneaking up on our forgetful protagonist and snatching his notes while he's sleeping.
  5. Enable URL rewriting by updating HitCount.jsp (supplied with the WebSphere server) as follows by changing:
    <FORM method=GET ACTION="HitCount">
    

    to

    
    <FORM method=GET ACTION=
    <%=response.encodeURL("HitCount") %>>
    

    Restart the example Web application to pick up the changed code, and try step 4 again. Now the count should increment regardless of whether the browser is accepting cookies. After selecting the Increment button and getting the response page, look at the URL in your browser. Now you can actually see your session ID.

  6. Start a HitCount session. Leaving the browser up, stop and start the application server, and try to increment the count again. It starts over; the old session ID, stored in memory, is gone.
  7. If you have an available data source (the default DataSource works fine for testing), select Enable Persistent Sessions in the Session Manager settings, stop and restart the application server, and try the above exercises again, especially step 6. Now you should see the count preserved even when the application server is restarted.

One more thing about HitCount: its interface presents the HttpSession as one more way to store data, along with persistent (data-based) Enterprise Java Beans (EJBs) and Java DataBase Connectivity (JDBC) calls. Don't be misled by HitCount or the term persistent sessions into confusing session data with business data. Even with persistence turned on, the data is lost when the session ends. Important information that the Web application captures, such as a purchase order or updated user preferences, still needs to be written to a database or entered into a workflow process, as with a traditional application.

Through all these exercises, we have to guess at what is or is not going on with our HttpSession object. Wouldn't it be nice if there were an easy way to view session data dynamically?

Snoop to the rescue
Fortunately, the Snoop servlet supplied with the WebSphere server and automatically deployed in the default configuration displays session data views. Most WebSphere developers are familiar with Snoop; the ability to successfully request it from a browser is used as a basic indication that the WebSphere server is up and running. Less well known is the fact that Snoop displays session information.

Use HitCount to start an HTTP session, and jump to the Snoop servlet by typing its URL in the browser. You should see a section in the Snoop output that looks similar to Figure 4.

Figure 4. Snoop display of HitCount session data
Fig 4

Session ID is the unique key created by the Session Manager to store and retrieve session data. Session values is a list of the current session's data elements. In this case, there is only one entry, hwcount, with a value of 1. Snoop displays your servlet's session data as well, as long as it is on the same application server.

The Snoop servlet uses several javax.servlet.http.HttpServletRequest and javax.servlet.http.HttpSession APIs to display this information:

  • HttpServletRequest.getSession(false) returns a session only if it already exists. This allows it to display the Session section of the page without inadvertently creating a new session.
  • HttpSession.getId() returns a String containing the current session ID.
  • HttpSession.getLastAccessedTime() and getCreationTime() return the last time a page was requested in this session and when the session was originally created, respectively (conveniently represented as milliseconds since midnight January 1, 1970 GMT).
  • HttpSession.getValueNames() returns an Enumeration of Strings, allowing Snoop to loop through the session data to print the table of session names and values, as shown in Figure 4.
  • The HttpServletRequest. isRequestedSessionIdFromCookie() and isRequestedSessionIdFromURL() methods check whether the session ID came from a cookie or rewritten URL and return a boolean value.

Now we can more easily make sense of the experiments we tried earlier. Try them again, and this time enter the URL for Snoop after each increment. You can see when a new session (as indicated by a session ID) is created, when an old session is preserved, and when no session is created. Use the same technique to examine your Web applications.

Conclusion
We have introduced the basic concept of managing Web sessions using the WebSphere Session Manager component and the HTTPSession interface. Now our hero can sleep well at night, knowing his essential information is safe and secure.

References

  • The WebSphere product provides the Snoop and HitCount servlets and source code and automatically deploys the servlets as part of the default configuration. You can find the source code files in your WebSphere installation directories.
  • Ayers, Danny, et al., Professional Java Server Programming
  • Wahli, Ueli, et al., Servlet and JSP Programming with IBM WebSphere and VisualAge for Java.

Resources

IBM DeveloperToolbox
Find the following article-related categories, products, or tools on your DeveloperToolbox CDs.

  • Categories: Java tools, WebSphere
  • IBM WebSphere Application Server Advanced Edition

About the author
Photo: Steve Eaton Steve Eaton is a software engineer for the IBM WebSphere technical support team. He holds a Bachelor of Arts degree in English Language and Literature from the University of Chicago and a Master of Science degree in Computer Science from the University of North Texas. You can contact him at
steaton@us.ibm.com.


131KB e-mail it!
What do you think of this article?
Killer! (5) Good stuff (4) So-so; not bad (3) Needs work (2) Lame! (1)

Comments?


  About IBM  |  Privacy  |  Terms of use  |  Contact