Session Management
http://xml.apache.org/http://www.apache.org/http://www.w3.org/

Main
Dev Guide

Webapps
Overview
Session Contexts
Authentication
Portal

Introduction

A session is a data storage which resides on the server and records information about one single user. Cocoon creates a session on demand and from that point of time the user is tracked and information can be stored inside the session. Each following request of this user is linked to the one specific session, so there is always only one session per user on the server.

To avoid a fast growing amount of sessions on the server and the overcome potential security problems, a session has usually a valid period of time. If during this period no new request comes in from the user, the session object on the server will be destroyed by the server (this period of time is called session timeout). The web application often allows a user to explictly destroy a session.

The usual web applications create sessions during login of a user and destroy them when the user logs out.

This document describes the basic Cocoon session management using the session transformer.

The chapter "Special Contexts" explains some special contexts which do not require a session. They are available everytime. These special contexts are the request context and the temporary context.

Session Tracking

If a user has a session, Cocoon is able to connect new requests from this user to the session of the user. This is done by session tracking. Basically, the session tracking of Cocoon uses the session tracking of the environment, which is usually the servlet engine.

There are two methods for session tracking: cookies and url rewriting. If you use cookies, you don't have to care about session tracking. Just refer to the documentation of your servlet engine on how to turn on cookies for session handling.

URL rewriting instead is a little bit complicated. For url rewriting, each link the user can select, needs a special session ID appended to this link. Unfortunately, this is not done automatically by Cocoon or the servlet engine. You can either do this by hand or you can use the encodeURL transformer just before the html serializer.

Sessions

The session action is responsible for creating and terminating a session. It is controlled by a sitemap parameter named "action". This parameter can have the values "create" and "terminate". If no parameter is set, it defaults to "create".

The action either creates a new session immediately (if not already available), or terminates it (if available).

Contexts
session Transformer

The session transformer is responsible for interpreting the tags and performing the actions required. The session transformer is configured in the sitemap and can be used inside a document. All tags must be prefixed with the session namespace. So the actual tag used in the document will read <session:xxxx>. The current namespace URI for the session transformer is "http://apache.org/cocoon/session/1.0".

Context-Tags

A context is basically an application specific block of XML data in the users session. Each context has a unique name.

The command createcontext is used to create a new context. A name attribute must be given to the context in order to identify it. The following names may not be used: request, response, session, context, temp, portal or authentication. If a context of the same name already exists then this command will have no effect.

<createcontext name="mycontext"/>

In order to delete a context the command deletecontext is provided. Again a name attribute must be provided.

<deletecontext name="mycontext"/>

Once created, XML data can then be stored inside or read from a given context.

Accessing context data

The data in a context can be dynamically accessed using the following commands.

getxml allows data to be read out of a context. A path attribute describes the source of the data inside the context and consists of an XPath expression. All path values must be absolute and only nodes and attributes can be accessed.

An optional default value can also be provided to allow for the nonexistence of the requested data.

<getxml context="mycontext" path="/User/Name"/>

<getxml context="mycontext" path="/User/Name">Matthew</getxml>

Attributes can also be accessed.

<getxml context="mycontext" path="/User/Name/@Age"/>

Data can be written into a context using the setxml command. It is possible to set values or nodes as the following examples show.

<setxml context="mycontext" path="/User/Name"/>Carsten</setxml>

<setxml context="mycontext" path="/User/"/><Name>Carsten</Name></setxml>

Using the setxml command causes all the nodes below the target node to be deleted. If you wish to maintain the nodes and manipulate individual branches of the XML tree - then the session transformer offers the mergexml command.

Use the removexml command to remove nodes from the context.

<removexml context="mycontext" path="/User/"/>

Example

The following example shows the use of several commands and in particular how the mergexml command can be used to manipulate context data.

<resource xmlns:session="http://apache.org/cocoon/session/1.0">
  <session:createcontext name="trackdemo"/>
  <!-- build context data -->
  <session:setxml context="trackdemo" path="/">
    <context>
      <users>
        <user id="1">
          <name>Carsten</name>
        </user>
      </users>
    </context>
  </session:setxml>
  <session:mergexml context="trackdemo" path="/context">
    <users>
      <user id="1">
        <name>Ziegeler</name>
        <developer>true</developer>
      </user>
      <user id="2">
        <name>Walter</name>
      </user>
    </users>
  </session:mergexml>
  <session:getxml context="trackdemo" path="/"/>
</resource>

In the above example, a context for storing data is added. Using the setxml command data is then stored into the context. The following mergexml command then changes the name of user-1 and adds a further tag. As there is no original user-2 the complete subtree is then added to the context.

Reading and writing contexts

Aside from the described means of accessing data in a context, the session transformer also provides for the reading and writing of contexts. This can be used to write an application context out to a database or to read an application context in from a file.

The session transformer offers a very flexible way of defining the source of the context data. It is possible to specify a resource (defined in the sitemap) or a Java class. Using a resource allows for example the context data to be read from a database using the SQL Transformer. As this source is a Cocoon pipeline, the data can be generated and transformed before passing into the context.

When a context is created, it can get additional save and load URIs which are used for loading/saving to/from the context:

<createcontext name="mycontext" load="cocoon://load-from-db" save="cocoon://save-to-db"/>

These URIs can then be used inside a document to load data into a context:

<loadxml context="mycontext"/>

This example would then load the context data via the resource load-from-db which must be defined in the sitemap.

Parameters can be passed to and interpreted by the uri or the Java class. This allows the context data to be read dependent on say the current user.

<loadxml context="mycontext"><user>ben</user></loadxml>

The resource addressed by the uri will receive the parameters as request-parameters. In addition the name of the context will always be passed as contextname.

Writing context data works in the same manner.

<savexml context="mycontext"/>

Both commands can use the optional path attribute:

<loadxml context="mycontext" path="/user"/>

<savexml context="mycotnext" path="/user"/>

The first command will read xml from the uri and store it in the context under the node user, the second one saves only the xml subtree under the node user to the uri. The resource addressed by the uri will be passed in addition to the contextname parameter the path parameter with the corresponding value. If the path attribute is not present the path parameter will get the value "/".

Special Contexts

Cocoon creates and maintains special contexts that allow the applications to access the environment. This allows the read-only access to such things as the current request using the same XPath commands previously described. These context do not require any session, they are always available and change on every request.

The Request Context - Accessing the Environment, Part One

The request context is an XML description of the current (HTTP) request. This context is a special read only context that can be accessed with the usual commands:

<getxml context="request" path="/parameter"/>

For example, if you want to get the value of a parameter with the name username you can include the following command in your XML and it will be replaced with the value of the parameter:

<getxml context="request" path="/parameter/username"/>

If you wish to obtain the complete querystring as it was passed into Cocoon - without converting the data to XML - then you can use the "/querystring" path:

<getxml context="request" path="/querystring"/>

The result will be a string in the format "?param=aaa&...".

The complete context you can access via these commands has the following XML format:

<parameter>
  <!-- All parameters: parameter names build the elements with the value of the first parameter with
                          this name as text node child -->
  <firstparameter>value of parameter</firstparameter>
  <secondparameter>value of parameter</secondparameter>
</parameter>

<querystring>the querystring with a leading '?' or empty<querystring>
  (The querystring contains only parameters send by the GET method)

<parametervalues>
  <!-- All parameters. The tags are all inside the cinclude transformer namespace.
    The generated XML can be used without modification for the
    cinclude:includexml command. -->
  <cinclude:parameters>
    <cinclude:parameter>
      <cinclude:name>1st parameter name</cinclude:name>
      <cinclude:value>1st parameter value</cinclude:value>
    </cinclude:parameter>
             ...
    <cinclude:parameter>
      <cinclude:name>2nd parameter name</cinclude:name>
      <cinclude:value>2nd parameter value</cinclude:value>
    </cinclude:parameter>
  </cinclude:parameters>
  <!-- If a parameter has more than one value, for each value a
      <session:param> block is generated. -->
</parametervalues>

<attributes>
  <!-- lists all attributes, attribute names build the elements
        with the values as text node childs -->
</attributes>

<headers>
  <!-- lists all headers, header names build the elements
       with the values as text node childs -->
</headers>

<cookies>
  <!-- lists all cookies -->
  <cookie name="...">
    <value>the cookie value</value>
    <name>the name of the cookie</name>
    <comment>value</comment>
    <domain>value</domain>
    <path>value</path>
    <maxAge>value</maxAge>
    <secure>value</secure>
    <version>value</version>
  </cookie>
</cookies>

<characterEncoding>value</characterEncoding>
<contentLength>value</contentLength>
<contentType>value</contentType>
<protocol>value</protocol>
<remoteAddress>value</remoteAddress>
<remoteHost>value</remoteHost>
<scheme>value</scheme>
<serverName>value</serverName>
<serverPort>value</serverPort>
<method>value</method>
<contextPath>value</contextPath>
<pathInfo>value</pathInfo>
<pathTranslated>value</pathTranslated>
<remoteUser>value</remoteUser>
<requestedSessionId>value</requestedSessionId>
<requestURI>value</requestURI>
<servletPath>value</servletPath>
<isRequestedSessionIdFromCookie>value</isRequestedSessionIdFromCookie>
<isRequestedSessionIdFromCookie>value</isRequestedSessionIdFromCookie>
<isRequestedSessionIdValid>value</isRequestedSessionIdValid>
The Temporary Context

The temporary context with the name "temp" is available on each request. It is independent from the session and has no content when a new request starts. It can be used like any other context except that the content is lost/deleted when the current response is finished.

Using the tempory context it is possible to store any XML information for processing the current request.

Form Handling

To get feedback or information from a user, forms are commonly used to present input field in the browser. The usual approach for form handling in web application consists of two steps. The first request presents the form to the user. This form initiates a second request that processes the form values.

Cocoon supports this two step process, in addition Cocoon offers a single step approach.

The common approach

The common approach consists of two steps or of creating two resources. The first resource defines the form: All input fields are declared, each gets a unique name. This form invokes the second resource.

This resource uses the session transformer to get the values provided by the user. The values are added by the browser to the parameters of the request. So using the request context and getxml, the values can be fetched.

If you want to create a form with two values - forename and surname of the user, you could generate a base xml file with the information about this form:

<page>
  <form>
    <action>form-handling-page</action>
    <input name="forename" type="text"/>
    <input name="surname" type="text"/>
  </form>
</page>

A stylesheet can transform this into valid html. The action tag indicates that the "form-handling-page" should be invoked by submitting the values.

The "form-handling-page" is a pipeline which is declared in the sitemap and uses the session transformer. It could also read the following xml:

<page xmlns:session="http://apache.org/cocoon/session/1.0">
  <forename>
    <session:getxml context="request" path="/parameter/forename"/>
  </forename>
  <surname>
    <session:getxml context="request" path="/parameter/surname"/>
  </surname>
</page>

As the form values are appended to the request, getxml with specifying the path (which is the parameter name used for the input field) inserts the value submitted by the user into the xml stream.

If you want to write the information in a session context, you must wrap the whole xml inside a setxml:

<page xmlns:session="http://apache.org/cocoon/session/1.0">
  <session:setxml context="userdata" path="/user">
    <forename>
      <session:getxml context="request" path="/parameter/forename"/>
    </forename>
    <surname>
      <session:getxml context="request" path="/parameter/surname"/>
    </surname>
  </session:setxml>
</page>

The user data is now stored inside the session context "userdata", so the context has the following content:

<user>
  <forename>Walter</forename>
  <surname>Walterson</surname>
</user>
The Session Framework approach

The previous chapter showed the common approach for handling form values. It forces the user to create two resources for a single form handling.

Cocoon offers an advanced approach. Only one single resource is created. This resources contains the information about the input fields used and in addition the information about where the submitted values should be stored inside the session.

The example from the previous chapter could look like this:

<page xmlns:session="http://apache.org/cocoon/session/1.0">
  <session:form name="myform">
    <session:action>the-next-page</session:action>
    <session:content>
      <session:inputxml name="forename" type="text" context="userdata" path="/user/forename"/>
      <session:inputxml name="surname" type="text" context="userdata" path="/user/surname"/>
    </session:content>
  </session:form>
</page>

The form tag starts the form definition. The name attribute is required to distinct between different forms on the same page. The action tag defines the url invoked by the form and the content tag describes the content of the form: its input fields.

The inputxml tag tells Cocoon that the following request contains form values which should be stored in the specified context under the given path. The session transformer transforms by removing the namespace and the context attribute:

<page xmlns:session="http://apache.org/cocoon/session/1.0">
  <form action="the-next-page">
    <inputxml name="forename" type="text"/>
    <inputxml name="surname" type="text"/>
  </form>
</page>

A stylesheet can now generate the appropriate html (or any other format). The main difference is, that the resource invoked by submitting the values has not to care about the form as Cocoon maintains the form handling. The only prerequisit is that a session for the current user and a session context to store the information exists.

The Cocoon approach allows a very easy way of form handling where the resource which creates the form also handles the form.

For editing values - if the context already contains information about the user - inputxml inserts the current value inside the tag. So the xml streamed would after a second run would look like this:

<page xmlns:session="http://apache.org/cocoon/session/1.0">
  <form action="the-next-page">
    <inputxml name="forename" type="text">Walter</inputxml>
    <inputxml name="surname" type="text">Walterson</inputxml>
  </form>
</page>

Like getxml it is also possible to provide default values for the input field, if the context does not contain any information:

<session:inputxml name="forename" context="userdata" path="/user/forename">
     Defaultname
</session:inputxml>
Copyright © 1999-2002 The Apache Software Foundation. All Rights Reserved.