Search code examples
servletsstack-overflowinfinite-loop

Servlet running into infinite loop when calling request.getRequestDispatcher


I'm trying to make a start servlet (Start.java) that is the entry point into my very simple website. Currently I have two mappings for this start servlet:

@WebServlet({"/Start", "/Start/*"})

When the user first loads the page (when invoking http://localhost:8080/MyApp/Start) a form page is loaded (Form.jspx) for them to fill out (the details of the form aren't important to the problem I'm having). What I want to do is have another jsp page (Done.jspx) load when the user loads this page: http://localhost:8080/MyApp/Start/Restore. When this page is called, I am using an unmarshaller to restore some data into my database from an XML file. The Done.jspx page simply displays how many rows were inserted from the XML file, but again I don't think this is important to my problem.

The problem I'm having is in my doGet method where I'm checking if Restore is in the URI or not. If it isn't, I load the default page which is Form.jspx. If it is in the URI, I call the request dispatcher to forward to Done.jspx. This is causing an infinite loop since when I call the dispatcher on Done.jspx it loads http://localhost:8080/MyApp/Start/Done.jspx which matches the mapping above (/Start/*) and causes the servlet to go into an infinite loop at the line where I'm loading the Form.jspx page (see below) which eventually causes a stack overflow.

The following is my doGet method

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    String URI = req.getRequestURI();
    System.out.println("URI: " + URI);

    if (URI.endsWith("Restore")) {
        String filename = this.getServletContext().getRealPath("/export/backup.xml");
        model.setPath(this.getServletContext().getRealPath("/export"));
        try {
            int n = model.importXML(filename);
            req.setAttribute("numInserted", n);
            req.getRequestDispatcher("Done.jspx").forward(req, resp);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }                                                           //load default form page
    else {
        req.getRequestDispatcher("Form.jspx").forward(req, resp);
    }
}

I'm still very new to Java EE and servlets so it is possible that I'm going about this problem in the wrong way. I'm wondering if there is a way around this or if I'm dealing with the different URI patterns incorrectly.


Solution

  • The problem is about the "/Start/*" pattern. It will redirect/forward /Start/Done.jspx to the servlet, too. And this wouldn't what you are expecting.

    You should make two different servlets, one for /Start, and the other for /Start/Restore

    --Edited--

    As your situation, you should use @WebServlet({"/Start", "/Start/Restore"}) instead.