javajakarta-eeservletsservlet-3.0

Servlet forward response to caller/previous page


I'm trying to forward a servlet response to the same page from when it came from (a.k.a.: the previous page, or the "servlet" caller).

I've seen many answers (like this and this) but still can't make it work.

I usually do the following to redirect the response of a servlet to another page:

request.getRequestDispatcher("MyNewPage").forward(request, response);

But I've tried to change "MyNewPage" for other options I've seen as solutions as:

request.getRequestDispatcher((String)request.getAttribute("javax.servlet.forward.request_uri")).forward(request, response);
request.getRequestDispatcher(request.getHeader("referer")).forward(request, response);

and other options and can't make it work.

What am I doing wrong?


Solution

  • First of all the request.getHeader("referer") returns a full URL but you have to strip off the http://server[:port]/ because what you pass to request.getRequestDispatcher() is added to the application context like this:

    /NameOfApp/http:/localhost:8084/NameOfApp/test.jsp
    

    Which is not what you want because you just need to pass the following to the dispatcher method:

    test.jsp
    

    If we take things from the start the first request starts from this URL:

    http://localhost:8084/RequestDispatcher/test.jsp
    

    The forward works but the second time you are going make a request to your Servlet, the Servlet will forward to itself. So you will enter a loop with the Servlet calling itself. Why will this happen? Since you call the Servlet from the form, this means that the URL address in your browser address box will change to that of your Servlet after the first request.

    http://localhost:8084/RequestDispatcher/NewServlet
    

    The Servlet will forward the request back to the JSP page and the browser will display just that but the URL in the browser address box will still be the one containing the Servlet and not the JSP page:

    http://localhost:8084/RequestDispatcher/NewServlet
    

    So the next time you hit submit the Servlet will try to forward the request to itself. If I were you I would use a redirect. It seems more appropriate for your purpose:

    response.sendRedirect(request.getHeader("referer"));
    

    This will always change the URL in your browser address box and prevent your Servlet from looping. This will have an impact on the request parameters but you can always add them on the redirect URL(if it's not sensitive information) or store them in session until you retrieve them on the next first request which will be made by the redirect.

    A framework like JSF would save you from these issues.

    The easiest solution that would allow you to use forward, is a hidden parameter in the form keeping the JSP(viewid) that called the Servlet instead of using the request.getHeader("referer"). You will need to check for loops though, because someone could deliberately change the value to force your Servlet container to loop and eventually crash the VM. But you can just use a request attribute to keep record of the previous request in the chain and if it's the same you respond with an error. So in the servlet you would use the hidden field value in order to decide where to forward to:

    request.getRequestDispatcher(request.getParameter("viewid")).forward(request, response);
    

    and in your JSP:

    <input type="hidden" name="viewid" value="test.jsp">
    

    I think this would cover your requirements.