1

I am using Jetty. My default servlet is making a simple forward to an HTML file in my WEB-INF folder that is causing a java.lang.StackOverFlowError error. The error is fixed if I rename the file I am forwarding from a .html to .jsp

DefaultServlet.java

public class DefaultServlet extends HttpServlet{

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) 
        throws ServletException, IOException{
            req.getRequestDispatcher("WEB-INF/home.html").forward(req, resp);

    }
}

web.xml

<web-app>
    <display-name>Archetype Created Web Application</display-name>
    <servlet>
        <servlet-name>Default</servlet-name>
        <servlet-class>DefaultServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>Default</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

My guess is that instead of inserting the html content in the response body, the forward is sending the browser a redirect to /WEB-INF/home.html. This again calls the DefaultServlet and gets into an infinity loop. How can I prevent this?

Thanks.

nknj
  • 2,436
  • 5
  • 31
  • 45

2 Answers2

3

The "default servlet", which is mapped on a special URL pattern of /, is a very special servlet which is invoked when there's a request which does not match any of the servlets mapped on a more specific URL pattern such as *.jsp, /foo/*, etc.

When you forward to home.html, for which apparently no one servlet is registered, then the default servlet is invoked once again. However, the default servlet is ignorantly forwarding to the very same HTML file once again instead of actually serving the requested HTML file. It'll on the forward still find no one servlet matching the forward URL and it'll still invoke the default servlet once again. And again. Etc. When this is performed so many times that the stack cannot keep track anymore of all those in sequence invoked doGet() methods (usually around 1000), then you'll get a StackOverflowError.

That it works with a JSP file has actually a very simple reason: there's already a JspServlet registered on an URL pattern of *.jsp. So the badly designed default servlet isn't invoked.

Your default servlet should instead be obtaining the HTML file's contents via ServletContext#getResourceAsStream() and write it to the HttpServletResponse#getOutputStream().

However, it's also quite possible that you completely misunderstood the whole meaning of "default servlet" and/or the special meaning of the URL pattern / and actually merely want a servlet acting as home page. In that case, you should be mapping the servlet on a more specific URL pattern (and please rename the currently obviously quite confusing class name DefaultServlet to something else):

<servlet>
    <servlet-name>home</servlet-name>
    <servlet-class>com.example.HomeServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>home</servlet-name>
    <url-pattern>/home</url-pattern>
</servlet-mapping>

And then register exactly that URL as welcome file:

<welcome-file-list>
    <welcome-file>home</welcome-file>
</welcome-file-list>
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
0

You need kind of exclude urls ends with "html".

See for example this link explaining similar problem solution Can I exclude some concrete urls from <url-pattern> inside <filter-mapping>?

Community
  • 1
  • 1
StanislavL
  • 56,971
  • 9
  • 68
  • 98