[Building Sakai] session variables in JSR-168 portlet

John A. Lewis jlewis at unicon.net
Thu Apr 9 15:11:50 PDT 2009


Tobias,

According to the JSR-168 specification, you can share session
information between portlets and servlets in the same webapp:

"PLT.15.4 Relationship with the Web Application HttpSession: A Portlet
Application is also a Web Application. The Portlet Application may
contain servlets and JSPs in addition to portlets. Portlets, servlets
and JSPs may share information through their session.  The
PortletSession must store all attributes in the HttpSession of the
portlet application. A direct consequence of this is that data stored in
the HttpSession by servlets or JSPs is accessible to portlets through
the PortletSession in the portlet application scope. Conversely, data
stored by portlets in the PortletSession in the portlet application
scope is accessible to servlets and JSPs through the HttpSession.  If
the HttpSession object is invalidated, the PortletSession object must
also be invalidated by the portlet container. If the PortletSession
object is invalidated by a portlet, the portlet container must
invalidate the associated HttpSession object."

However, doing this in practice can be somewhat tricky.

The main problem that arises is with how application servers identify
the user's session. Generally the session identifier is stored on the
browser with a cookie named JSESSIONID. The URL path for this session
cookie is usually scoped to the specific webapp where the user session
exists. Since all of the user interaction with a portlet will actually
go through the portal webapp (and then talk to the portlet webapp via
cross-context requests on the server), the session identifier that will
be used will come from the portal webapp session cookie. Any requests to
a servlet in the same webapp as the portlet will be on a different URL
path, which means the server will not see the existing JSESSIONID cookie
and will generate a new one with a different value. This results in the
user having two different HttpSession objects in the portlet webapp –
one that uses the JSESSIONID value from the portal webapp and one that
uses the JSESSIONID from the portlet webapp. Since the portlets and
servlets are using different HttpSession objects, they cannot in fact
share session information.

There is a fix for this problem available in Tomcat 5.5.4 and higher. In
order to get requests for the two different webapps to use the same
session identifier, you need the path on the JSESSIONID cookie to be
less restrictive. To do that, you need to add emptySessionPath="true" to
the Connector declaration in the server.xml file. It should end up
looking something like this:

<Connector port="8080"
                   maxThreads="150" minSpareThreads="25"
maxSpareThreads="75"
                   enableLookups="false" redirectPort="8443"
acceptCount="100"
                   connectionTimeout="20000" disableUploadTimeout="true"
                   emptySessionPath="true" />

This will cause the path on the JSESSIONID cookie to be empty and will
allow all webapps on the same same Tomcat instance to use the same
session identifier. It is important to realize that this does not mean
that all the webapps will share the same session – each webapp will
still have its own separate HttpSession object for each user. It just
means that the session in each webapp will use the same identifier and
will allow you to realize the behavior described in PLT.15.4.

Hope that helps!

John


> Hi all,
>
> I'm trying to move a JSR-168 portlet into Sakai-2.5.x . I have the
> problem that I can't find out how to get to the session variables which
> are set by the portlet in the servlet that it belongs to.
>
> We currently use in the portlet:
>
> PortletSession portletSession = request.getPortletSession();
> portletSession.setAttribute(namespace + XMLRPC_SERVER_ATTRIBUTE,
>                     xmlRpcServer,PortletSession.APPLICATION_SCOPE);
>
> in the servlet we try to get the thing back using
>
> xmlRpcServer = getJspContext().getAttribute(
>         namespace + PagPortlet.XMLRPC_SERVER_ATTRIBUTE,
>         PageContext.SESSION_SCOPE);
>
> unfortunately this returns null rather than the attribute.
>
> looking through the set attributes  using:
>
> Enumeration attributes = getJspContext().getAttributeNamesInScope(
>         PageContext.SESSION_SCOPE);
> while (attributes.hasMoreElements()) {
>     System.err.println(
>          " attr: " + attributes.nextElement());
> }
>
> they don't seem to be existent at all.
>
> Is there something we do wrong for sakai as we think this is JSR-168 ?
>
> Thanks for your help
>
> Tobias


More information about the sakai-dev mailing list