How can I manually load a Java session using a JSESSIONID?
There is no API to retrieve session by id.
What you can do, however, is implement a session listener in your web application and manually maintain a map of sessions keyed by id (session id is retrievable via session.getId()). You will then be able to retrieve any session you want (as opposed to tricking container into replacing your current session with it as others suggested)
A safe way to do it is to set the jsession id in the cookie - this is much safer than setting it in the url.
Once it is set as a cookie, then you can retrieve the session in the normal way using
request.getSession();
method.setRequestHeader("Cookie", "JSESSIONID=88640D6279B80F3E34B9A529D9494E09");
If you are using Tomcat, you ask tomcat directly (but it's ugly). I bet there are other hacky solutions for other web servers.
It uses an instance of the "Manager" interface to manage the sessions. What makes it ugly is that I haven't found a nice public interface to be able to hook into, so we have to use reflection to get the manager.
Below is a context listener that grabs that manager on context startup, and then can be used to get the Tomcat Session.
public class SessionManagerShim implements ServletContextListener {
static Manager manager;
@Override
public void contextInitialized(ServletContextEvent sce) {
try {
manager = getManagerFromServletContextEvent(sce);
} catch (NoSuchFieldException | IllegalAccessException e) {
e.printStackTrace();
}
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
manager = null;
}
private static Manager getManagerFromServletContextEvent(ServletContextEvent sce) throws NoSuchFieldException, IllegalAccessException {
// Step one - get the ApplicationContextFacade (Tomcat loves facades)
ApplicationContextFacade contextFacade = (ApplicationContextFacade)sce.getSource();
// Step two - get the ApplicationContext the facade wraps
Field appContextField = ApplicationContextFacade.class.getDeclaredField("context");
appContextField.setAccessible(true);
ApplicationContext applicationContext = (ApplicationContext)
appContextField.get(contextFacade);
// Step three - get the Context (a tomcat context class) from the facade
Field contextField = ApplicationContext.class.getDeclaredField("context");
contextField.setAccessible(true);
Context context = (Context) contextField.get(applicationContext);
// Step four - get the Manager. This is the class Tomcat uses to manage sessions
return context.getManager();
}
public static Session getSession(String sessionID) throws IOException {
return manager.findSession(sessionID);
}
}
You can add this as a listener in your web.xml and it should work.
Then you could do this to get a session.
There is no way within the servlet spec, but you could try:
manually setting the cookie in the request made by Flash
or doing as Taylor L just suggested as I was typing and adding the jsessionid parameter the path of the URI.
Both methods will tie your app to running on a servlet container that behaves like Tomcat; I think most of them do. Both will also require your Flash applet asking the page for its cookies, which may impose a JavaScript dependency.