Tomcat shares multiple web application sessions.
Implementation of tomcat sharing multiple web application sessions
Problem
Today, a friend asked a question about two Java web pages under tomcat, one for the mall and the other for the live streaming. After logging on to the mall, he jumped to the live streaming, non-Logon status is found.
Solution
- Extract the session into a session service and operate the session through the service.
- Tomcat uses the session manager to retrieve sessions within all the context.
Solution 1
Override the session method.
Solution 2
After finding the source code, we can find that we can traverse all sessions in the context. When we first obtain the session, if the cressContext attribute is true, if the session ID exists in all the contexts, the system tries to traverse all the contexts when the session ID is not obtained. If the session ID exists, the system creates its own session Object Based on the session ID in the context.
public HttpSession getSession(boolean create) { if (crossContext) { // There cannot be a session if no context has been assigned yet if (context == null) return (null); // Return the current session if it exists and is valid if (session != null && session.isValid()) { return (session.getSession()); } HttpSession other = super.getSession(false); if (create && (other == null)) { // First create a session in the first context: the problem is // that the top level request is the only one which can // create the cookie safely other = super.getSession(true); } if (other != null) { Session localSession = null; try { localSession = context.getManager().findSession(other.getId()); if (localSession != null && !localSession.isValid()) { localSession = null; } } catch (IOException e) { // Ignore } if (localSession == null && create) { localSession = context.getManager().createSession(other.getId()); } if (localSession != null) { localSession.access(); session = localSession; return session.getSession(); } } return null; } else { return super.getSession(create); } }
Use the following operations to obtain cross-application sessions through context:
request.getSession().getServletContext().getContext("/app2").getAttribute("att2");
This is because the request will obtain the session object based on the cookie's sessionid. In this case, the session object will not be found because a session object has been created based on other sessionids, then, the getContext operation obtains the context of the corresponding url and performs the session operation.
public ServletContext getContext(String uri) { // Validate the format of the specified argument if (uri == null || !uri.startsWith("/")) { return null; } Context child = null; try { // Look for an exact match Container host = context.getParent(); child = (Context) host.findChild(uri); // Non-running contexts should be ignored. if (child != null && !child.getState().isAvailable()) { child = null; } // Remove any version information and use the mapper if (child == null) { int i = uri.indexOf("##"); if (i > -1) { uri = uri.substring(0, i); } // Note: This could be more efficient with a dedicated Mapper // method but such an implementation would require some // refactoring of the Mapper to avoid copy/paste of // existing code. MessageBytes hostMB = MessageBytes.newInstance(); hostMB.setString(host.getName()); MessageBytes pathMB = MessageBytes.newInstance(); pathMB.setString(uri); MappingData mappingData = new MappingData(); ((Engine) host.getParent()).getService().findConnectors()[0].getMapper().map( hostMB, pathMB, null, mappingData); child = (Context) mappingData.context; } } catch (Throwable t) { ExceptionUtils.handleThrowable(t); return null; } if (child == null) { return null; } if (context.getCrossContext()) { // If crossContext is enabled, can always return the context return child.getServletContext(); } else if (child == context) { // Can still return the current context return context.getServletContext(); } else { // Nothing to return return null; } }
If you have any questions, please leave a message or go to the community on this site for discussion. Thank you for reading this article. Thank you for your support!