I am experimenting with setting the cookie path in my application's web.xml (as suggested here) to:
<session-config>
<cookie-config>
<path>/</path>
</cookie-config>
</session-config>
So I deploy two identical web applications to localhost:8080/application-a
and localhost:8080/application-b
respectively.
Each application is a single servlet:
public class ControllerServlet extends HttpServlet{
@Override
public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
HttpSession session = req.getSession(false);
if (session == null) {
session = req.getSession(true);
System.out.printf("No session was present - new one created with JSESSIONID=[%s]\n", session.getId());
} else {
System.out.printf("JSESSIONID cookie was present and HttpSession objects exists with JSESSIONID=[%s]\n", session.getId());
}
}
}
I deploy the apps to a Tomcat 8.5 container (tried with Tomcat 9 as well the behavior is the same). When I visit with my browser the application-a
, here's what I see:
… and on the Tomcat logs I read:
No session was present - new one created with JSESSIONID=[A227B147A4027B7C37D31A4A62104DA9]
So far so good. When I then visit application-b
here's what I see:
… and the Tomcat logs show:
No session was present - new one created with JSESSIONID=[5DC8554459233F726628875E22D57AD5]
This is also very well as explained here and also in this answer and I quote:
SRV.7.3 Session Scope
HttpSession objects must be scoped at the application (or servlet context) level. The underlying mechanism, such as the cookie used to establish the session, can be the same for different contexts, but the object referenced, including the attributes in that object, must never be shared between contexts by the container.
So even though on the request the JSESSIONID
cookie was present, my application (the one deployed in application-b
) was unable to find an HttpSession object in its own servlet context scope and so a new session object was created and a new value was assigned to the JSESSIONID
cookie.
However, when I now go back to my application-a
I find out that because of the /
value configured for the cookie path, it is now trying to use the JSESSIONID
value set by application-b
and of course its servlet doesn't find such a session object in its own context (application-a
) and so a new value for the JSESSIONID
cookie is created which will in turn invalidate the session of the application-b
application and so on and so forth ad infinitum as I switch back and forth between the two applications.
So my questions are:
1 given the above behavior it would seem impossible for two applications to use the same JSESSIONID
cookie value as the key to their respective HttpSession objects. So in fact not only are the HttpSession objects always different and scoped at the application (servlet context) level but also, in practice, the JSESSIONID
values have to be different. Is that correct?
2 If so, then why does the servlet specification use the wording:
The underlying mechanism, such as the cookie used to establish the session, can be the same for different contexts [...]
The only way I can imagine the above could be accomplished would be to have a way to hardcodedly provide the JSESSIONID
value to use when a new session object is created? But I don't see an API for that.
3 Is there a way I can have some other cookies be shared among applications using the /
path in the <session-config> XML element but not have the /
path apply to the JSESSIONID
cookie? In other words does the <session-config> apply to all cookies of an application or only the cookie used for session tracking? (JSESSIONID
) ?
JSESSIONID is a cookie generated by Servlet containers and used for session management in J2EE web applications for HTTP protocol. If a Web server is using a cookie for session management, it creates and sends JSESSIONID cookie to the client and then the client sends it back to the server in subsequent HTTP requests.
In your Java server, you should call cookie. setPath("/") before adding it to response. Such cookie will match all request URIs.
To Start off the JSESSIONID is stored in a cookie. If cookies are turned off, you have to get into url rewritting to store the jsessionid in the url. There is nothing else about the session in cookies.
Upon further experimentation and taking a cue from this answer it would appear that for the same JSESSIONID to be used for all web applications it is necessary to set the following attribute in context.xml:
<Context ... sessionCookiePath="/">
Either the Tomcat-wide context.xml or the WAR-specific context.xml will do. The <cookie-config><path>
value configured in the WAR's web.xml is apparently ignored.
Regarding point 3 of my question I 've found that the way to set paths for other cookies is to programmatically create many of them, one for each path, and add them in the response object with the addCookie method. The configurations in web.xml
or context.xml
are appicable to other cookies beyond the session cookie.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With