25

I have been looking at solutions for sharing session data between mutliple war files. I came across the following solution http://www.fwd.at/tomcat/sharing-session-data-howto.html

The basic idea of it is that if you have more than one war file, you can set a cookie using the sessionid of the first context that is used.

The cookie can be set using a path that will apply to all contexts/applications.

For example, if I have the following configuration for 3 applications

/myapp/app1
/myapp/app2
/myapp/app3

I can set a cookie as follows

/myapp sessionid.

The sessionid cookie will then be sent to any request with /myapp in the address. This allows the session id to then be used by any of the contexts.

The only problem with this approach is that it was written in 2003 and tested on Tomcat 4.

What are your opinions of this approach? Is there a better way of doing it?

Thanks

flavio.donze
  • 7,432
  • 9
  • 58
  • 91
ziggy
  • 15,677
  • 67
  • 194
  • 287

4 Answers4

46

That article is indeed heavily outdated.

On Tomcat 5.5 and 6.0 you can just set emptySessionPath attribute to true in the <Connector> element in /conf/server.xml.

<Connector ... emptySessionPath="true">

On Tomcat 7.0 this has changed because this is now configureable from the Servlet 3.0 API on. It's then on Tomcat's side configureable by setting sessionCookiePath to / in <Context> element in any responsible context.xml file.

<Context ... sessionCookiePath="/">

As said, there's a new Servlet 3.0 API which allows you to configure the session cookie through the standard API. You can do it either declaratively by adding the following to the web.xml:

<session-config>
    <cookie-config>
        <path>/</path>
    </cookie-config>
</session-config>

or programmatically by SessionCookieConfig which is available by ServletContext#getSessionCookieConfig().

getServletContext().getSessionCookieConfig().setPath("/");

You could do this in ServletContextListener#contextInitialized() or HttpServlet#init().

See also:

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • This is very useful information. I dont quite understand how most of it works but at least it gives me a pointer to where and what to investigate further. Are there any examples anywhere of how these are used? I am using Tomcat 6.0 – ziggy Feb 25 '12 at 12:38
  • The `/conf/server.xml` is in Tomcat's installation folder. Just open the XML file in a text/xml editor, locate the `` element which is been used to serve your webapps and add `emptySessionPath="true"` attribute to the element. – BalusC Feb 25 '12 at 12:43
  • If i set emptySessionPath to true, do all applications get the same jsessionid or do they still get different jsessionids? Thanks – ziggy Feb 25 '12 at 12:49
  • setting cookie path on `web.xml` also works in Glassfish, indeed – Alex Salauyou Jul 17 '14 at 19:26
  • In Tomcat 9 (http://stackoverflow.com/q/40753753/274677) it seems that the element in `web.xml` is ignored. All that matters is the value of the attribute `sessionCookiePath` in either the tomcat-wide `context.xml` (in `/conf`) or the WAR-specific `context.xml` in `META-INF`. Can you please clarify your answer whether BOTH `context.xml` and `web.xml` need to be set or EITHER and what's the precedence? In my experience only `context.xml` is used. There is also no mention of `web.xml` here: http://tomcat.apache.org/tomcat-7.0-doc/config/context.html – Marcus Junius Brutus Nov 23 '16 at 00:45
  • I have multiple subdomains with a common domain name all running within the same app so I want to share the session but I also have multiple sets of these with other, completely different subdomains with a different common name running in the same Tomcat instance. I would like the cookie domain for each to be set to the common domain, but with different domains I need to set this on a per domain basis when creating a session for the first time. Is that even possible? – Volksman Dec 12 '19 at 16:00
2

To my knowledge there is no direct way to do this, you can however use a domain level cookie if these contexts share the same domain.

You can either put the data in the cookie (I don't recommend that).

Or put a secured session Id that you can use to access some form of storage (DB or distributed cache etc) to retrieve the data you need.

MahdeTo
  • 11,034
  • 2
  • 27
  • 28
1

For Tomcat 8 I use the following configuration to share a session across 2 webapps:

conf/context.xml

<Context sessionCookiePath="/">

    <Valve className="org.apache.catalina.valves.PersistentValve"/>
    <Manager className="org.apache.catalina.session.PersistentManager">
        <Store className="org.apache.catalina.session.FileStore" directory="${catalina.base}/temp/sessions"/>
    </Manager>

    ...

</Context>

I deploy the same simple webapp twice log.war and log2.war:

/log
/log2

I can now log-in to /log and have the user displayed in /log2, this does not work with the tomcat default configuration.

enter image description here

The session value is set and read:

HttpSession session=request.getSession();  
session.setAttribute("name",name);

HttpSession session=request.getSession(false);  
String name=(String)session.getAttribute("name");  

I used this project as example: https://www.javatpoint.com/servlet-http-session-login-and-logout-example

Most examples/solutions use a in-memory database which requires more setup work:

flavio.donze
  • 7,432
  • 9
  • 58
  • 91
1

If the amount of data is not astronomical and the data itself isn't changing too rapidly, you might want to consider using JNDI. This solution was designed exactly for what you are looking for.

You can have a look at official documentation or this post to tomcat-user mailing list for references & examples.

mindas
  • 26,463
  • 15
  • 97
  • 154