I'm very new to Spring + Tomcat and trying to learn it while working on an existing spring boot (v. 2.6.x) web app running on a Tomcat server (tomcat-embed-core v. 9.0.x).
The application serves URLs of this type:
-
\{customer}\path\to\resource -
\{customer}\newapp\path\to\resource
I can see this reported on the ModelAndView controller annotated with the likes of PostMapping and GetMapping.
Now, the service keeps tracks of sessions using JSESSION cookies and generating session IDs using tomcat's standard org.apache.catalina.SessionIdGenerator.
I would like to programmatically change the format of the session identifier generated by tomcat, depending on the request being served.
Given the paths above, for instance, I'd like to have:
- request to 1. above, should be generating session identifiers like
905A6892CB2C12F84A331F58A6A2C382 - requests to
newapp, i.e. 2. above, should be generating session identifiers likeNEWAPP_905A6892CB2C12F84A331F58A6A2C382
The format of the session is irrelevant, but they must have a different prefix.
It seems that one way to achieve this would be to have two different contexts, each one with a different catalina Manager, which can be set using org.apache.catalina.Context#setManager.
I'm not able to define two different contexts because the root in the path is the variable {customer}, nor I'm able to dynamically inject the context using an implementation of org.apache.catalina.valves.ValveBase, as there is no easy way to create a delegated context, where the only difference WRT the base tomcat context is the Manager.
I've tried changing the root of the newapp paths to be like newapp\{customer}\path\to\resource and creating a new Context for newapp, but this fails if I try to override org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory#getWebServer like
@Override
public WebServer getWebServer(ServletContextInitializer... initializers) {
Tomcat tomcat = new Tomcat();
File baseDir = createTempDir("tomcat");
tomcat.setBaseDir(baseDir.getAbsolutePath());
prepareContext(tomcat.getHost(), initializers);
final String documentRoot = getValidDocumentRoot().getAbsolutePath();
final Context ctx = tomcat.addContext("/newapp", documentRoot);
ctx.setManager(new NewAppManager());
return getTomcatWebServer(tomcat);
}
returning a 404 error - it looks like the application is not able to find the mapping for the path, even if I successfully changed the GetMapping to newapp\{customer}\path\to\resource.
Can anyone suggest the best way to achieve this and if what I'm trying even makes sense?
Thank you so much!
I was able to achieve the required outcome by adding a few lines in the
getWebServermethod.Adding the whole method below, with comments, for clarity.