It's funny cause all this problem is solved when you use WebFlow and a flow mapping as your welcome file.
My web.xml:
Code:
<servlet-mapping>
<servlet-name>myservelt</servlet-name>
<url-pattern>/app/*</url-pattern>
</servlet-mapping>
<welcome-file-list>
<!-- Redirects to a custom page for dispatcher handling -->
<welcome-file>app/welcome</welcome-file>
</welcome-file-list>
Then if you have a flow whose id is 'welcome' then both http://server/appcontext and http://server/appcontext/app/welcome will be mapped to the same flow.
That is because FlowHandlerMapping calls FlowUrlHandler.getFlowId(request) which calls request.getPathInfo() returning "/welcome" as the required mapping when the welcome file is used.
On the other hand, AbstractUrlHandlerMapping (which is the base for most MVC controller handler mappings) calls UrlPathHelper.getLookupPathForRequest(request) where you can find this method:
Code:
/**
* Return the path within the servlet mapping for the given request,
* i.e. the part of the request's URL beyond the part that called the servlet,
* or "" if the whole URL has been used to identify the servlet.
* <p>Detects include request URL if called within a RequestDispatcher include.
* <p>E.g.: servlet mapping = "/test/*"; request URI = "/test/a" -> "/a".
* <p>E.g.: servlet mapping = "/test"; request URI = "/test" -> "".
* <p>E.g.: servlet mapping = "/*.test"; request URI = "/a.test" -> "".
* @param request current HTTP request
* @return the path within the servlet mapping, or ""
*/
public String getPathWithinServletMapping(HttpServletRequest request) {
String pathWithinApp = getPathWithinApplication(request); // <- This is "/"
String servletPath = getServletPath(request); // <-This is "/app
if (pathWithinApp.startsWith(servletPath)) {
// Normal case: URI contains servlet path.
return pathWithinApp.substring(servletPath.length());
}
else {
// Special case: URI is different from servlet path.
// Can happen e.g. with index page: URI="/", servletPath="/index.html"
// Use servlet path in this case, as it indicates the actual target path.
return servletPath;
}
}
And then it will return servletPath ("/app") when the welcome file path should be sending it to "/welcome". I wonder if the solution would simply be to change the method to return request.getPathInfo() instead of servletPath, like this:
Code:
else {
// Special case: URI is different from servlet path.
// Can happen e.g. with index page: URI="/", servletPath="/index.html"
String pathInfo = request.getPathInfo();
if (pathInfo != null) {
return pathInfo;
}
return servletPath;
}