Previous Contents Index Next |
Sun Java System Application Server Standard and Enterprise Edition 7 2004Q2 Developer's Guide to Web Applications

> ## Chapter 4
> Creating and Managing User Sessions

> This chapter describes how to create and manage a session that allows users and transaction information to persist between interactions.

> This chapter contains the following sections:

> - Introducing Sessions
> - How to Use Sessions
> - Enabling the Availability Service (Enterprise Edition)
> - Session Managers

> ##

> Introducing Sessions

> The term user session refers to a series of user application interactions that are tracked by the server. Sessions are used for maintaining user specific state, including persistent objects (like handles to EJB components or database result sets) and authenticated user identities, among many interactions. For example, a session could be used to track a validated user login followed by a series of directed activities for a particular user.

> The session itself resides in the server. For each request, the client transmits the session ID in a cookie or, if the browser does not allow cookies, the server automatically writes the session ID into the URL.

> The Sun Java System Application Server supports the servlet standard session interface, called HttpSession, for all session activities. This interface enables you to write portable, secure servlets.

> The rest of this section includes these topics:

> - Sessions and Cookies
> - Sessions and URL Rewriting
> - Sessions and Security
> - Distributed Sessions and Persistence (Enterprise Edition)

> ### Sessions and Cookies

> A cookie is a small collection of information that can be transmitted to a calling browser, which retrieves it on each subsequent call from the browser so that the server can recognize calls from the same client. A cookie is returned with each call to the site that created it, unless it expires.

> Sessions are maintained automatically by a session cookie that is sent to the client when the session is first created. The session cookie contains the session ID, which identifies the client to the browser on each successive interaction. If a client does not support or allow cookies, the server rewrites the URLs where the session ID appears in the URLs from that client.

> You can configure whether and how sessions use cookies in the following ways:

> - You can configure the session-properties for the entire web container:
> - To use the Administration interface, select Containers and then Web Container under your server instance. Then click on the Properties button under Session Configuration Properties. After editing the properties, click on OK, then Save.
> - You can also edit the session-properties element in the server.xml file, which is the same as the corresponding element in the sun-web.xml file. For details, see the Sun Java System Application Server Administrator’s Configuration File Reference.
> - You can configure the session-properties and cookie-properties elements in the sun-web.xml file for an individual web application. The sun-web.xml file is described in Chapter 6, “Assembling and Deploying Web Modules.”

> ### Sessions and URL Rewriting

> You can configure whether sessions use URL rewriting in the following ways:

> - You can configure the session-properties for the entire web container:
> - To use the Administration interface, select Containers and then Web Container under your server instance. Then click on the Properties button under Session Configuration Properties. After editing the properties, click on OK, then Save.
> - You can also edit the session-properties element in the server.xml file, which is the same as the corresponding element in the sun-web.xml file. For details, see the Sun Java System Application Server Administrator’s Configuration File Reference.
> - You can configure the session-properties element in the sun-web.xml file for an individual web application. The sun-web.xml file is described in Chapter 6, “Assembling and Deploying Web Modules.”

> ### Sessions and Security

> The Sun Java System Application Server security model is based on an authenticated user session. Once a session has been created the application user is authenticated (if authentication is used) and logged in to the session. Each interaction step from the servlet that receives an EJB request does two things: generates content for a JSP to format the output, and checks that the user is properly authenticated.

> Additionally, you can specify that a session cookie is only passed on a secured connection (that is, HTTPS), so the session can only remain active on a secure channel.

> For more information about security, see Chapter 5, “Securing Web Applications.”

> ### Distributed Sessions and Persistence (Enterprise Edition)

> A distributed session can run in multiple Sun Java System Application Server instances, provided the following criteria are met:

> - Each server instance has the same distributable web application deployed to it. The web-app element of the web.xml deployment descriptor file must have the distributable subelement specified.
> - Each server instance has access to the same Sun Java System high-availability database (HADB). For information about how to enable this database, see Enabling the Availability Service (Enterprise Edition).
> - The web application uses high-availability session persistence. If a non-distributable web application is configured to use high-availability session persistence, an error is written to the server log. See PersistentManager.
> - All objects bound into a distributed session must be of the types listed in the Object Types Supported for J2EE Web Application Session State Failover table.

> Note | Contrary to the Servlet 2.3 specification, Sun Java System Application Server does not throw an IllegalArgumentException if an object type not supported for failover is bound into a distributed session. You should keep the distributed session size as small as possible. Session size has a direct impact on overall system throughput.

> A servlet that is not deployed as part of a web application is implicitly deployed to a default web application and has the default ServletContext. The default ServletContext is not distributed. (A web application with an empty context root does not have the default ServletContext.)

> In the event of an instance or hardware failure, another server instance can take over a distributed session, with the following limitations:

> - If a distributable web application references a J2EE component or resource, the reference may be lost. See the Object Types Supported for J2EE Web Application Session State Failover table for a list of the types of references that HTTPSession failover supports.
> - References to open files or network connections are lost.

> For information about how to work around these limitations, see the Sun Java System Application Server Application Design Guidelines for Storing Session State.

> In the following table, No indicates that failover for the object type may not work in all cases and that no failover support is provided. However, failover may work in some cases for that object type. For example, failover may work because the class implementing that type is serializable.

> For more information about the InitialContext, transaction recovery, and Administered Objects, see the Sun Java System Application Server Developer's Guide to J2EE Services and APIs. For more information about local and remote EJB references, see the Sun Java System Application Server Developer's Guide to Enterprise JavaBeans Technology.

> Table 4-1 Object Types Supported for J2EE Web Application Session State Failover

> Java Object Type | Failover Support
> --- | ---
> EntityBean local home reference, local object reference | Yes
> Stateful SessionBean local home reference | Yes
> Stateful SessionBean local object reference | Yes
> Stateless SessionBean local home reference, local object reference | Yes
> Co-located EntityBean remote home reference, remote reference | Yes
> Co-located Stateful SessionBean remote home reference | Yes
> Co-located Stateful SessionBean remote reference | Yes
> Co-located Stateless SessionBean remote home reference, remote reference | Yes
> Distributed EntityBean remote home reference, remote reference | Yes
> Distributed Stateful SessionBean remote home reference, remote reference | Yes
> Distributed Stateless SessionBean remote home reference, remote reference | Yes
> JNDI Context | Yes, InitialContext and java:comp/env
> UserTransaction | Yes, but if the instance that fails is never restarted, any prepared global transactions are lost and may not be correctly rolled back or committed
> JDBC DataSource | No
> Java™ Message Service (JMS) ConnectionFactory, Destination | No
> JavaMail™ Session | No
> Connection Factory | No
> Administered Object | No
> Web service reference | No
> Serializable Java types | Yes

> ##

> How to Use Sessions

> To use a session, first create a session using the HttpServletRequest method getSession(). Once the session is established, examine and set its properties using the provided methods. If desired, set the session to time out after being inactive for a defined time period or invalidate it manually. You can also bind objects to the session which store them for use by other components.

> The rest of this section includes these topics:

> - Creating or Accessing a Session
> - Examining Session Properties
> - Binding Data to a Session
> - Invalidating a Session

> ### Creating or Accessing a Session

> To create a new session or to gain access to an existing session, use the HttpServletRequest method getSession(), as shown in the following example:

> HttpSession mySession = request.getSession();

> getSession() returns the valid session object associated with the request, identified in the session cookie which is encapsulated in the request object. Calling the method with no arguments, creates a session if one does not already exist which is associated with the request. Additionally, calling the method with a Boolean argument creates a session only if the argument is true.

> The following example shows the doPost() method from a servlet which only performs the servlet’s main functions, if the session is present. Note that, the false parameter to getSession() prevents the servlet from creating a new session if one does not already exist:

> public void doPost (HttpServletRequest req,
> HttpServletResponse res)
> throws ServletException, IOException
> {
> if ( HttpSession session = req.getSession(false) )
> {
> // session retrieved, continue with servlet operations
> }
> else
> // no session, return an error page
> }
> }

> Note | The getSession() method should be called before anything is written to the response stream. Otherwise the SetCookie string is placed in the HTTP response body instead of the HTTP header.

> For more information about getSession(), see the Java Servlet Specification v2.3.

> ### Examining Session Properties

> Once a session ID has been established, use the methods in the HttpSession interface to examine session properties, and methods in the HttpServletRequest interface to examine request properties that relate to the session.

> The following table shows the methods to examine session properties.

> Table 4-2 HttpSession Methods

> HttpSession method | Description
> --- | ---
> getCreationTime() | Returns the session time in milliseconds since January 1, 1970, 00:00:00 GMT.
> getId() | Returns the assigned session identifier. An HTTP session’s identifier is a unique string which is created and maintained by the server.
> getLastAccessedTime() | Returns the last time the client sent a request carrying the assigned session identifier (or -1 if its a new session) in milliseconds since January 1, 1970, 00:00:00 GMT.
> isNew() | Returns a Boolean value indicating if the session is new. Its a new session, if the server has created it and the client has not sent a request to it. This means, the client has not acknowledged or joined the session and may not return the correct session identification information when making its next request.

> For example:

> String mySessionID = mySession.getId();
> if ( mySession.isNew() ) {
> log.println(currentDate);
> log.println("client has not yet joined session " + mySessionID);
> }

> The following table shows the methods to examine servlet request properties.

> Table 4-3 HttpServletRequest Methods

> HttpServletRequest Methods | Description
> --- | ---
> getRemoteUser() | Gets the requesting user name (HTTP authentication can provide the information). Returns null if the request has no user name information.
> getRequestedSessionId() | Returns the session ID specified with the request. This may differ from the session ID in the current session if the session ID given by the client is invalid and a new session was created. Returns null if the request does not have a session associated with it.
> isRequestedSessionIdValid() | Checks if the request is associated to a currently valid session. If the session requested is not valid, it is not returned through the getSession() method.
> isRequestedSessionIdFromCookie() | Returns true if the request’s session ID provided by the client is a cookie, or false otherwise.
> isRequestedSessionIdFromURL() | Returns true if the request’s session ID provided by the client is a part of a URL, or false otherwise.

> For example:

> if ( request.isRequestedSessionIdValid() ) {
> if ( request.isRequestedSessionIdFromCookie() ) {
> // this session is maintained in a session cookie
> }
> // any other tasks that require a valid session
> } else {
> // log an application error
> }

> ### Binding Data to a Session

> You can bind objects to sessions in order to make them available across multiple user interactions.

> The following table shows the HttpSession methods that provide support for binding objects to the session object.

> Table 4-4 HttpSession Methods

> HttpSession Methods | Description
> --- | ---
> getAttribute() | Returns the object bound to a given name in the session or null if there is no such binding.
> getAttributeNames() | Returns an array of names of all attributes bound to the session.
> setAttribute() | Binds the specified object into the session with the given name. Any existing binding with the same name is overwritten. An object bound into a distributed session must implement the java.io.Serializable interface. See Distributed Sessions and Persistence (Enterprise Edition).
> removeAttribute() | Unbinds an object in the session with the given name. If there is no object bound to the given name this method does nothing.

> ##### Binding Notification with HttpSessionBindingListener

> Some objects require you to know when they are placed in or removed from, a session. To obtain this information, implement the HttpSessionBindingListener interface in those objects. When your application stores or removes data with the session, the servlet engine checks whether the object being bound or unbound implements HttpSessionBindingListener. If it does, the Sun Java System Application Server notifies the object under consideration, through the HttpSessionBindingListener interface, that it is being bound into or unbound from the session.

> ### Invalidating a Session

> Specify the session to invalidate itself automatically after being inactive for a defined time period. Alternatively, invalidate the session manually with the HttpSession method invalidate().

> Tip | The session API does not provide an explicit session logout API, so any logout implementation must call the session.invalidate() API.

> ##### Invalidating a Session Manually

> To invalidate a session manually, simply call the following method:

> session.invalidate();

> All objects bound to the session are removed.

> ##### Setting a Session Timeout

> Session timeout is set using the sun-web.xml deployment descriptor file. For more information, see the session-properties element in Chapter 6, “Assembling and Deploying Web Modules.”

> ##

> Enabling the Availability Service (Enterprise Edition)

> This section describes how to enable the Sun Java System high-availability database (HADB) for session persistence. For information about how to set up and configure this database, see the Sun Java System Application Server Administrator’s Guide. You should should set the same availability value for all instances in a cluster to ensure consistent behavior.

> Availability can be enabled at five different levels:

> 1. The server instance
> 2. The web container
> 3. The application
> 4. The web module
> 5. The web application itself

> For availability to be enabled at a given level, it must be enabled at all higher levels as well. For example, to enable availability at the application level, you must also enable it at the server instance and web container levels.

> The default for a given level is the setting at the next level up. For example, if availability is enabled at the web container level, it is enabled by default at the application level.

> When availability is disabled at the server instance level (the default setting), enabling it at any other level has no effect. When availability is enabled at the server instance level, it is enabled at all levels unless explicitly disabled.

> The following sections describe how to enable availability:

> - Server Instance and Web Container Levels
> - Application and Web Module Levels
> - Web Application Level

> ### Server Instance and Web Container Levels

> You can enable availability at the server instance and web container level in these ways:

> - Using the Administration Interface
> - Using the asadmin Command
> - Editing the server.xml File

> ##### Using the Administration Interface

> To enable availability at the instance and web container level using the Administration interface, follow these steps:

> 1. Open the Availability Service component under your server instance.
> 2. Go to the Availability Service page.
> 3. Check the Instance Level Availability box.
> 4. Make sure that Web Container Availability is set to either Enabled or Specified by Instance.
> 5. Click on the Save button.
> 6. Click Properties under Persistence Store Properties.
> 7. In the Name field, type store-pool-jndi-name.
> 8. In the Value field, type the JNDI name of the HADB JDBC Resource. The assumed default is jdbc/hastore. For more information, see the Administration Guide.
> 9. Click on the Save button.
> 10. Go to the server instance page.
> 11. Apply Changes and restart the server.

> ##### Using the asadmin Command

> To enable availability at the web container level, use the asadmin set command as follows, then restart the server:

> asadmin set --user admin_user [--password admin_password] [--passwordfile password_file] [--host localhost] [--port 4848] [--secure | -s] instance_name.web-container.availabilityEnabled=true

> ##### Editing the server.xml File

> The store-pool-jndi-name property in the server.xml file specifies that the HADB is used for session persistence. Note that availability-enabled="true" must also be set. The element hierarchy in the server.xml file looks like this when the HADB is configured and availability is enabled for the server instance:

> <server name="server1" ... >
> ...
> <availability-service availability-enabled="true">
> <persistence-store>
> <property name="store-pool-jndi-name" value="jdbc/hastore"/>
> </persistence-store>
> </availability-service>
> ...
> </server>

> For information about how to configure the persistence store, see the Administration Guide.

> To enable availability at the web container level, set availability-enabled="true" in the web-container element of the server.xml file as follows, then restart the server:

> <server name="server1">
> ...
> <web-container ... availability-enabled="true"/>
> ...
> </server>

> ### Application and Web Module Levels

> You can enable availability at the application or web module level during deployment. For details, see “Deploying Web Applications” on page 96.

> As an alternative, you can edit the server.xml file. To enable availability at the application level, set availability-enabled="true" in the j2ee-application element of the server.xml file as follows, then restart the server:

> <server name="server1">
> ...
> <applications>
> ...
> <j2ee-application
> name="MyApp"
> location="instance_dir/applications/j2ee-apps/MyApp"
> availability-enabled="true">
> </j2ee-application>
> ...
> </applications>
> ...
> </server>

> To enable availability at the web module level, set availability-enabled="true" in the web-module element of the server.xml file as follows, then restart the server:

> <server name="server1">
> ...
> <applications>
> ...
> <web-module
> name="MyWebApp"
> context-root=""
> location="instance_dir/applications/j2ee-modules/MyWebApp"
> availability-enabled="true">
> </web-module>
> ...
> </applications>
> ...
> </server>

> ### Web Application Level

> If the Availability Service is disabled, there is no high availability for HTTP session persistence. In other words, persistence-type=memory.

> If the Availability Service is enabled, high availability for HTTP session persistence is enabled for all applications by default. If no further configuration exists either in the server.xml or sun-web.xml file, the default session persistence configuration is as follows:

> persistence-type=ha

> persistenceFrequency=time-based

> persistenceScope=session

> The availability setting applies unconditionally to all web applications deployed to the server instance with the persistence-type set to ha.

> You can override this default configuration for all applications in server.xml. For details, see the Sun Java System Application Server Administrator’s Configuration File Reference. You can override this default configuration for a specific application in sun-web.xml. For details, see Session Managers.

> The Availability Service setting also determines whether single sign-on, if configured, is highly available.

> Note | Enabling the Availability Service is not sufficient for configuring session persistence. For details, see Distributed Sessions and Persistence (Enterprise Edition).

> ##

> Session Managers

> A session manager automatically creates new session objects whenever a new session starts. In some circumstances, clients do not join the session, for example, if the session manager uses cookies and the client does not accept cookies. Sun Java System Application Server 7 gives you these session management options:

> - StandardManager, the default session manager
> - PersistentManager, a provided session manager that uses a persistent data store

> Note | The session manager interface is Unstable. An unstable interface may be experimental or transitional, and hence may change incompatibly, be removed, or be replaced by a more stable interface in the next release. If the session manager configuration contains an error, the error is written to the server log and the StandardManager default configuration is used.

> ### StandardManager

> The StandardManager is the default session manager. By default this session manager provides no session persistence. However, you can configure it so that the session state is written to the file system prior to server shutdown. This session manager is not designed for a production environment.

> #### Enabling StandardManager

> To specify StandardManager for the entire web container, perform these tasks:

> 1. Open the Containers component under your server instance.
> 2. Go to the Web Container page.
> 3. Click on the Session Manager tab.
> 4. Change the Persistence Type to Memory.
> 5. Click on the Properties button under Properties.
> 6. Enter the names and values of any properties that you want to change from the default values. For a list of properties, see Manager Properties for StandardManager.
> 7. Click on the OK button.
> 8. Click on the Save button.

> To specify StandardManager for a specific web application, edit the sun-web.xml file as in the following example. The persistence-type property is optional. This overrides the web container settings for the web application.

> <sun-web-app>
> ...
> <session-config>
> <session-manager persistence-type=memory>
> <manager-properties>
> <property name="reapIntervalSeconds" value="20" />
> </manager-properties>
> </session-manager>
> ...
> </session-config>
> ...
> </sun-web-app>

> For more information about the sun-web.xml file, see Chapter 6, “Assembling and Deploying Web Modules.”

> #### Manager Properties for StandardManager

> The following table describes manager-properties properties for the StandardManager session manager.

> Table 4-5 manager-properties Properties

> Property Name | Default Value | Description
> --- | --- | ---
> reapIntervalSeconds | 60 | Specifies the number of seconds between checks for expired sessions. You should set this value lower than the frequency at which session data changes. For example, this value should be as low as possible (1 second) for a hit counter servlet on a frequently accessed website, or you could lose the last few hits each time you restart the server.
> maxSessions | -1 | Specifies the maximum number of sessions that can be in cache, or -1 for no limit. After this, an attempt to create a new session causes an IllegalStateException to be thrown.
> sessionFilename | none; state is not preserved across restarts | Specifies the absolute or relative path to the directory in which the session state is preserved between application restarts, if preserving the state is possible. A relative path is relative to the temporary directory for this web application.

> ### PersistentManager

> The PersistentManager is the other session manager provided with Sun Java System Application Server. For session persistence, PersistentManager can use either of the following stores, to which each session is serialized:

> - A file - Provides session persistence to the local file system, and allows a single server instance to recover the session state after a failure and restart. The session state is persisted in the background, and the rate at which this occurs is configurable. This store also provides passivation and activation of the session state to help control the amount of memory used. This option is not supported in a production environment.
> - The Sun Java System high-availability database (HADB). The HADB allows sessions to be distributed. For details, see Distributed Sessions and Persistence (Enterprise Edition). In addition, you can configure the frequency and scope of session persistence. The HADB is also used as the passivation and activation store. Use this option in a production environment that requires session persistence.

> You must enable the HADB before you can use distributed sessions. See Enabling the Availability Service (Enterprise Edition).

> Note | The HADB setting is in the Sun Java System Application Server Enterprise Edition only.

> #### Enabling PersistentManager

> To specify PersistentManager for the entire web container, perform these tasks:

> 1. Open the Containers component under your server instance.
> 2. Go to the Web Container page.
> 3. Click on the Session Manager tab.
> 4. Change the Persistence Type to File or to Highly Available Database.
> 5. Click on the Properties button under Properties.
> 6. Enter the names and values of any properties that you want to change from the default values. For a list of properties, see Manager Properties for PersistentManager.
> 7. Click on the OK button.
> 8. Click on the Properties button under Session Store Properties.
> 9. Enter the names and values of any properties that you want to change from the default values. For a list of properties, see Store Properties for PersistentManager.
> 10. Click on the OK button.
> 11. Click on the Save button.

> To specify PersistentManager for a specific web application, edit the sun-web.xml file as in the following example. Note that persistence-type must be set to file or ha. This overrides the web container settings for the web application.

> <sun-web-app>
> ...
> <session-config>
> <session-manager persistence-type=ha>
> <manager-properties>
> <property name=persistenceFrequency value=web-method />
> </manager-properties>
> <store-properties>
> <property name=persistenceScope value=session />
> </store-properties>
> </session-manager>
> ...
> </session-config>
> ...
> </sun-web-app>

> For more information about the sun-web.xml file, see Chapter 6, “Assembling and Deploying Web Modules.”

> #### Manager Properties for PersistentManager

> The following table describes manager-properties properties for the PersistentManager session manager.

> Table 4-6 manager-properties Properties

> Property Name | Default Value | Description
> --- | --- | ---
> reapIntervalSeconds | 60 | Specifies the number of seconds between checks for expired sessions. If the persistence-type attribute of the session-manager element is file or ha, sessions are passivated if maxSessions has been exceeded. If persistenceFrequency is set to time-based, active sessions are stored at this interval. You should set this value lower than the frequency at which session data changes. For example, this value should be as low as possible (1 second) for a hit counter servlet on a frequently accessed website, or you could lose the last few hits each time you restart the server.
> maxSessions | -1 | Specifies the maximum number of sessions that can be in cache, or -1 for no limit. After this, an attempt to create a new session causes an IllegalStateException to be thrown. If the persistence-type attribute of the session-manager element is file or ha, the session manager passivates sessions to the persistent store when this maximum is reached.
> persistenceFrequency | web-method | Specifies how often the session state is stored. Allowed values are as follows: web-method - The session state is stored at the end of each web request prior to sending a response back to the client. This mode provides the best guarantee that the session state is fully updated in case of failure. time-based - The session state is stored in the background at the frequency set by reapIntervalSeconds. This mode provides less of a guarantee that the session state is fully updated. However, it can provide a significant performance improvement because the state is not stored after each request. Applicable only if the persistence-type attribute of the session-manager element is ha.

> #### Store Properties for PersistentManager

> The following table describes store-properties properties for the PersistentManager session manager.

> Table 4-7 store-properties Properties

> Property Name | Default Value | Description
> --- | --- | ---
> directory | instance_dir/generated/jsp/j2ee-apps/appname/appname_war | Specifies the absolute or relative path to the directory into which individual session files are written. A relative path is relative to the temporary work directory for this web application. Applicable only if the persistence-type attribute of the session-manager element is file.
> persistenceScope | session | Specifies how much of the session state is stored. Allowed values are as follows: session - The entire session state is stored every time. This mode provides the best guarantee that your session data is correctly stored for any distributable web application. modified-session - The entire session state is stored if it has been modified. A session is considered to have been modified if HttpSession.setAttribute() or HttpSession.removeAttribute() was called. You must guarantee that setAttribute() is called every time an attribute is changed. This is not a J2EE specification requirement, but it is required for this mode to work properly. modified-attribute - Only modified session attributes are stored. For this mode to work properly, you must follow some guidelines, which are explained immediately following this table. Applicable only if the persistence-type attribute of the session-manager element is ha.

> If the persistenceScope store property is set to modified-attribute, your web application should follow these guidelines:

> - Call setAttribute() every time you modify the session state.
> - Make sure there are no cross-references between attributes. The object graph under each distinct attribute key is serialized and stored separately. If there are any object cross references between the objects under each separate key, they are not serialized and deserialized correctly.
> - Ideally, the session state should be stored in multiple attributes, or at least in a read-only attribute and a modifiable attribute.

> Note | The session persistence scope modified-attribute is not certified as a full production quality feature. You should evaluate the performance and stability of the web container under expected peak load with this persistence scope. If exceptions are logged or response time is too high, do not use this persistence scope for your production environment. Use session or modified-session instead.

> Previous Contents Index Next

> Copyright 2004 Sun Microsystems, Inc. All rights reserved.