Working with sessions

HTTP is a stateless protocol. A web server receives a request, sends a response, then terminates the connection to the client. The web server does not maintain information about the client, so it cannot determine when another request comes from the same client. This inability to track clients and their navigation through a website makes it difficult to do any complex transactions on a website.

However, JRun supports a session object, which you can use to track a user throughout the entire interaction with the web server. With the session object, you can track users as they shop for items or send registration or preference information. You can also free users from re-entering information every time that they connect to your site.

The session object stores information for a particular user session. By default, JRun uses cookies to track sessions, but it can track sessions using URL rewriting, hidden form fields, or a custom method. The cookies themselves only contain an identification number (called the session ID) that matches a request to a session object on the server-side. When you use URL rewriting or hidden form fields, the session ID is passed not as a value of a cookie but as extra path information or a form field.

Variables stored in the session object are not discarded when the user jumps between pages in the application; instead, these variables persist for the entire user session. As long as the client keeps sending the session ID with the request, JRun is able to access user-specific session data for that client.

JRun creates a session object when any page from the application is requested by a user who does not already have a session. The web server destroys the session object when the session expires or is abandoned.

The session object retrieves a session ID from the client in several ways, depending on your configuration. The servlet API abstracts the exact details of the server getting the client's session ID. However, you must be aware of the differences between the various methods because they require different coding techniques.

The following table describes the various ways that you can implement the session object:
Persistence mechanism

Description
Cookie
The default state-management mechanism. Cookies store the session ID and the server retrieves it when the server components calls session-sensitive methods. A reference to the cookie is passed to the server with every request and back to the client with every response as an HTTP header.
This is the easiest method to implement because there are no special coding requirements. However, some browsers do not accept cookies.
Cookies are the default session mechanism.
Hidden form field
JRun attaches the session ID to all requests as a form field that is hidden to the user. To use this method, all pages must process POST requests.
For more information on using hidden form fields as your session mechanism, see "Using hidden form fields".
URL rewriting
JRun appends the session ID to all URLs as extra path information. You must encode all URLs in order for the session ID to be appended.
For more information on using URL rewriting as your session mechanism, see "Using URL rewriting".

In a simple implementation, your application might remember the user name; in a secure implementation, your application might remember the user name and password; in an e-commerce system, your application might maintain the shopping cart. In applications that do not use the servlet API, you typically store session information using an application-specific storage mechanism and return a key value to the browser through a hidden form field, URL query string, or a cookie. Subsequent requests use this key value to look up the previously stored session information.

A session object gives you a single location to store and retrieve information throughout a user's connection to your website.

You can access session information in servlets and JSPs:

The Java Servlet specification defines the HttpSession interface, which provides session-management functionality while shielding you from the implementation details. The HttpSession interface is available from the HttpServletRequest class.

When forwarding or including files that use sessions, the original request that created the session sets the cookie in the corresponding response object that is used in an include or forward method.

Establishing sessions

You use the getSession method to establish a session and the getAttribute method to access values from a session.

To establish a session:

  1. Establish the values to be saved in the session:
    public class SelectionForm extends HttpServlet {
    ��public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException {
    ����resp.setContentType("text/html");
    ����PrintWriter out = resp.getWriter();
    ����String thisName = "Unknown Name";
    ����// Get user name from login form.
    ����String[] attrArray = req.getParameterValues("myName");
    ����// We know that the calling form only has one value for myName.
    ����if(attrArray != null && attrArray.length > 0) {
    ������thisName = attrArray[0];
    ����}
    ��}
    ...
    
  2. Create a new session by calling the HttpServletRequest object's getSession method:
    // Create a session:
    HttpSession thisSession = req.getSession(true);
    
  3. Associate the attribute with the session using the session object's setAttribute method:
    // This example saves a user name.
    thisSession.setAttribute("name", thisName);
    

To access session information:

  1. Obtain a reference to the session object by calling the HttpServletRequest object's getSession method:
    ...
    public class DisplayInfo extends HttpServlet {
    
    public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { ��resp.setContentType("text/html"); ��PrintWriter out = resp.getWriter(); ��out.println("<html><head><title>Display Information</title></head><body>"); ��out.println("<h1>displayInfo Servlet</h1>"); ��// Get logged-in user from session object ��HttpSession thisSession = req.getSession(true); ...
  2. Use the HttpSession object's getAttribute method to access the attribute value. Ensure that you cast the result to the appropriate type:
    String userName = (String)thisSession.getAttribute("name");
    
  3. Use the attribute value in your code:
    if(userName != null) {
    ��out.println("<h2>Welcome " + userName + "</h2>");
    }
    

Configuring sessions

You can configure persistence and cookie settings in the jrun-web.xml file. You can also change the session time-out interval in your web application's web.xml deployment descriptor.

This section describes how to change settings by editing the jrun-web.xml and web.xml files. You can also configure the runtime session-management settings using the MBean View utility. The jrun.servlet.session.SessionService service defines session persistence. For more information on using MBean View, see JRun Administrator's Guide. JRun includes file and JDBC storage implementations of the session mechanism.

Changing session time-out

Session objects use a small amount of resources. While the session remains active, JRun leaves the session object alone. However, after a period of inactivity, JRun destroys session objects to free up unused resources.

The web.xml file defines one session-related element: session-config. This element has one subelement, session-timeout. The session-timeout element defines how many minutes a session object can be inactive before JRun persists it to a data store or destroys it (if persistence is disabled).

The default session time-out is 30 minutes. The maximum value is 34560 minutes (24 days). If you set session-time-out to 0 or any negative value, JRun does not time out or persist sessions after any period of inactivity. However, if too many sessions are created and not destroyed, JRun eventually persists the sessions to disk (or other persistence method) to maintain their state. This can cause a drain on performance and resources.

The following example shows setting the session time-out to 42 minutes in the web.xml file:

<web-app>
...
��<session-config>
����<session-timeout>42</session-timeout>
��</session-config>
...
</web-app>

When using cookies, you can also set a maximum age. That value indicates to the browser how long the cookie is valid. The cookie-max-age and session-timeout values define different settings. Once the session reaches its session time-out, JRun destroys the session object on the server side, as described in previously. On the browser side, once the cookie-max-age reaches the end of its lifespan, the browser destroys the cookie file. For more information, see "Configuring sessions in the jrun-web.xml file".

Configuring sessions in the jrun-web.xml file

You can configure most session settings at a per-web-application level using the web application's jrun-web.xml file. If you do not add any of the settings described in this section to the jrun-web.xml file, JRun uses the default values.

The session-config subelement, under the jrun-web-app root element, defines the session settings. Under session-config, you can configure the following subelements:
Element
Description
persistence-config
Defines persistence settings for all session methods (cookies, URLs, and hidden form fields). Persistence settings are used when the JRun server stops while there are still active sessions.
cookie-config
Specifies settings for the cookies used for session tracking.
replication-config
Specifies the configuration of session replication, which allows for session failover. Session replication only works when clustering is enabled and all of the buddies specified are within the given cluster.

The following sections describe each of these elements. For a sample configuration of session settings in the jrun-web.xml file, see "Example of session configuration".

persistence-config

The following table describes the available elements in the persistence-config element:
Element
Description
Default
active
Indicates if session persistence is enabled.
true
persistence-type
Specifies the default session storage provider to use. Valid values are file or jdbc.
For more information, see the JRun Administrator's Guide.
file
persistence-class
Specifies the class to be used as the session storage provider. Use this element when the persistence-type is not specified.
The class specified here must implement jrun.servlet.session.SessionStorage.
n/a
persistence-synchronized
Specifies whether session persistence writing is synchronized.
true
class-change-option
Specifies what to do with sessions when the classloader changes.
Valid values are reload, drop, ignore.
reload
session-swapping
Specifies if sessions are swapped out of memory to a storage service.
false
session-swap-interval
Specifies how often the session pool is checked for sessions that are swapped to a storage service. This is specified in seconds.
10
session-max-resident
Specifies the number of sessions that are allowed in memory before swapping to a storage service.
Due to delays in the session-swap-interval and sessions that might not be serializable, the actual maximum can differ. If set to 0, all session data will be written out immediately on completion of the request.
session-swapping must be set to true in order for this property to take effect.
9999999
init-param
Specifies initialization parameters to pass to the session storage provider. Subelements are param-name and param-value.
For more information on initialization parameters for the jdbc and file persistence-types, see the JRun Administrator's Guide.
n/a

cookie-config

The following table describes the available elements in the cookie-config element:
Element
Description
Default
active
Indicates if cookies are enabled.
true
cookie-max-age
Sets the cookie's maximum age, in seconds. This value is stored in the cookie on the browser side. Indicates to the browser how long the cookie is valid.
A positive value indicates that the browser deletes the cookie file after that many seconds have passed without interaction with the server.
A negative value or a value of zero indicates that the cookie is not stored by the browser after the current session completes.
The cookie-max-age and session-timeout values define different settings. Once the session reaches its session time-out, JRun destroys the session object on the server side, as described in "Changing session time-out". On the browser side, once the cookie-max-age reaches the end of its lifespan, the browser destroys the cookie file.
-1
cookie-secure
Indicates to the browser whether the cookie is sent only using a secure protocol, such as HTTPS or SSL.
false
cookie-domain
Sets the domain within which this cookie is presented.
A domain name begins with a dot (.foo.com) and means that the cookie is visible to servers in a specified Domain Name System (DNS) zone (for example, www.foo.com, but not a.b.foo.com). The form of the domain name is specified by RFC 2109.
By default, cookies are returned only to the server that sent them.
n/a
cookie-comment
Specifies a comment that describes a cookie's purpose. The comment is useful if the web browser presents the cookie to the user. Comments are not supported by Netscape Version 0 cookies.
n/a
cookie-path
Sets a path to which the client returns the cookie. The cookie is visible to all the pages in the directory you specify, and all the pages in that directory's subdirectories. A cookie's path must include the servlet that set the cookie; for example, /catalog, which makes the cookie visible to all directories on the server under /catalog.
/
cookie-name
Sets the session cookie name. It can contain only ASCII alphanumeric characters and cannot contain commas, semicolons, or white space, or begin with a $ character.
The name must conform to RFC 2109.
JSESSIONID

replication-config

The following table describes the available elements in the replication-config element:
Element
Description
Default
active
Indicates if session replication is enabled.
false
buddy-name
Specifies a specific server within the cluster to have local sessions replicated to. Set to * to replicate persisted sessions to all servers in the cluster. This is not recommended for larger clusters.
n/a

Example of session configuration

The following is an example of the persistence settings in the jrun-web.xml file:

<jrun-web-app>
...
��<session-config>
����<persistence-config>
������<active>true</active>
������<persistence-type>file</persistence-type>
������<persistence-synchronized>true</persistence-synchronized>
������<class-change-option>reload</class-change-option>
������<session-swapping>true</session-swapping>
������<session-swap-interval>5</session-swap-interval>
������<session-max-resident>500</session-max-resident>
������<init-param>
��������<param-name>foo</param-name>
��������<param-value>bar</param-value>
������</init-param>
����</persistence-config>
����<cookie-config>
������<active>true</active>
������<cookie-max-age>-1</cookie-max-age>
������<cookie-secure>true</cookie-secure>
������<cookie-domain>foo</cookie-domain>
������<cookie-comment>george</cookie-comment>
������<cookie-path>bar</cookie-path>
������<cookie-name>jsessionid</cookie-name>
����</cookie-config>
��</session-config>
...
</jrun-web-app>

Disabling cookies

You can disable cookies but still let JRun use other session persistence methods, such as URL rewriting or hidden form fields. To disable cookies in JRun, you change the value of the active element of cookie-config to false, as the following example shows:

...
<session-config>
��<cookie-config>
����<active>false</active> 
��</cookie-config>
</session-config>
...

Using URL rewriting

You can use URL rewriting as your session mechanism by disabling cookies and invoking the encodeURL method of the request object on URLs that you provide to the user. When JRun builds the encoded URL, JRun appends the session ID to the encoded URL as a query string parameter named JSESSIONID. Then, JRun can access the session object associated with that user by getting the session ID from the URL query string.

Enabling URL rewriting

You do not explicitly enable URL rewriting. If the client browser disables cookies or if you disable cookies, JRun uses URL rewriting without any interaction between you and the JRun configuration.

However, you must do the following things for JRun to use URL rewriting as a session mechanism:

Using rewritten URLs

To prepare your servlets or JSPs for URL rewriting, you must encode each URL that you return to the client with the request object's encodeURL method on a page that uses a session object. The following example encodes the URL:

String originalURL = "/servlet/URLRewriter";
String encodedURL = response.encodeURL(originalURL);
out.println("<P><a href=\"" + encodedURL + "\">This link contains a JSESSIONID</a> (if cookies are disabled)");

You must instantiate the session object before encoding the URL and committing any output to the client.

To see a sample servlet, start the samples JRun server and open a browser to http://localhost:8200/techniques.

Testing URL rewriting

There are several steps you must take to test URL rewriting on a local machine.

To test URL rewriting:

  1. Do one of the following:
  2. Write a servlet that creates a session object and encodes the URLs. An example is provided on the samples server.
  3. Compile the servlet.
  4. Open the page and put your mouse over the links on the page. You see ;JSESSSIONID=xxxxxxxxxxxxxxxxx appended to each URL, where the x's represent a session ID.

Customizing URL rewriting

You can explicitly enforce URL rewriting by appending the session ID to the end of the URI's path information after a semicolon. Although it often appears at the end of the URL, JSESSIONID is not a query string parameter, but rather part of the path information.

The following example explicitly sets the JSESSIONID parameter:

...
HttpSession thisSession = request.getSession(true);
String originalURL = "/servlet/Logger";
String newURL = originalURL + ";JSESSIONID=" + thisSession.getId() + request.getQueryString();
...

Using hidden form fields

You can use a hidden field submitted by the FORM tag to pass the session ID from the client to the server.

Using hidden form fields as a session mechanism has the following disadvantages:

To use hidden form fields, you create a session and then use that session's ID as the value of the session field in a FORM element. The following example shows a FORM in a servlet that passes the session ID from the client to the server when the FORM is submitted:

...
HttpSession session = request.getSession(true);
out.println("<FORM METHOD=\"POST\" ACTION=\"HiddenForm\">");
out.println("<INPUT TYPE=\"HIDDEN\" NAME=\"session\" VALUE=\"" + session.getId() + "\">");
out.println("<INPUT TYPE=\"Submit\" VALUE=\"Submit\"></FORM>");
...

To see a sample servlet, start the samples JRun server and open a browser to http://localhost:8200/techniques.

 

Send me an e-mail when comments are added to this page | Comment Report

Current page: http://livedocs.adobe.com/jrun/4/Programmers_Guide/techniques_servlet13.htm