StackOverflowError in servlet mapping with url-pattern "/*"

seo, servlet-filters, servlets, tomcat

Solution

A servlet which is mapped on `/*` will also run on `RequestDispatcher#forward()` calls. So if you're performing a forward in that servlet, it would call itself everytime in an infinite loop. That explains the `StackOverflowError`.

After all, you should not be using `/*` for servlets at all. It only makes sense on servlet filters. Put the servlet mapping back on a more specific URL pattern and create a filter on `/*` which forwards to the desired servlet when necessary. You of course don't want to have the servlet to handle for example images/CSS/JS files. Assuming that they're all placed in `/resources` folder and that your front controller is mapped on `/myservlet/*`, then do the following job in `doFilter()`:

HttpServletRequest req = (HttpServletRequest) request;
String path = req.getRequestURI().substring(req.getContextPath().length());

if (path.startsWith("/resources/")) {
    // Just let container's default servlet do its job.
    chain.doFilter(request, response);
}
else {
    // Delegate to your front controller.
    request.getRequestDispatcher("/myservlet" + path).forward(request, response);
}

See also:

- URL mapping in Tomcat to FrontController servlet

Problem

I have a set of JSP pages and I want to hide the .jsp extension (after a bit of research it seems it's good for SEO). One solution I came across was the following: ``` <servlet> <servlet-name>mypage</servlet-name> <jsp-file>/some-page.jsp</jsp-file> </servlet> <servlet-mapping> <servlet-name>mypage</servlet-name> <url-pattern>/some-page</url-pattern> </servlet-mapping> ``` And while this works, I believe I have to set up this mapping for every jsp page on my site. I came across another solution posted here (Easy friendly URL's): Hidden features of JSP/Servlet ... which uses a simple servlet to forward the request. In my web.xml I have the following and it works fine: ``` <servlet> <servlet-name>MyServletName</servlet-name> <servlet-class>myservlets.PrettyUrlServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>MyServletName</servlet-name> <url-pattern>/myservlet/*</url-pattern> </servlet-mapping> ``` Now the problem is I don't want to hit the URL: www.mydomain.com/myservlet/some-page I want to use the URL: www.mydomain.com/some-page So I changed the url-pattern to "/*" ``` <servlet> <servlet-name>MyServletName</servlet-name> <servlet-class>myservlets.PrettyUrlServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>MyServletName</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping> ``` But this causes an infinite loop: ``` Exception in thread "http-bio-8080-exec-1" java.lang.StackOverflowError at org.apache.catalina.core.ApplicationHttpRequest.getAttribute(ApplicationHttpRequest.java:219) at org.apache.catalina.core.ApplicationHttpRequest.getAttribute(ApplicationHttpRequest.java:228) . . at org.apache.catalina.core.ApplicationHttpRequest.getAttribute(ApplicationHttpRequest.java:228) at org.apache.catalina.core.ApplicationHttpRequest.getAttribute(ApplicationHttpRequest.java:228) at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:379) at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:329) at myservlets.PrettyUrlServlet.doGet(PrettyUrlServlet.java:22) ``` Which I'm not sure how to fix. Any ideas?

Original source

Related problems