Search code examples
javajakarta-eeservletsrequestdispatcher

request dispatcher forward is not forwarding after include of any servlet


Someone please HELP ME.

 private void forward(String address,
                    HttpServletRequest  request,
                    HttpServletResponse response)
                        throws ServletException, IOException{
    getServletContext()
        .getRequestDispatcher("/" + address)
        .forward(request, response);
}
private void include(String address,
                    HttpServletRequest  request,
                    HttpServletResponse response)
                        throws ServletException, IOException{
    getServletContext()
        .getRequestDispatcher("/" + address)
        .include(request, response);
}

These two functions have been written in every servlet in my project and the problem is that when I have used these two functions in a servlet at first include("servlet/abc",request.response); and after it have used forward("servlet/def",request.response); so using Netbeans 7 I have step by step watched that forward is not forwarding the control of servlet but when I don't use include before the forward its forwarding the control.

So I want to know that why it is happening and what's the reason and how can I do forward after include any servlet.

Please someone HELP ME ...it's an interesting question.

include("servlet/abc",request, response);


forward("servlet/def",request, response);   //HERE IS PROBLEM NOT FORWRDING AFTER INCLUDE

Solution

  • Regardless of exactly why you seem to observe this behavior, what you're attempting will never work. Per the contract of RequestDispatcher.forward(), "If the response already has been committed, this method throws an IllegalStateException," and "Uncommitted output in the response buffer is automatically cleared before the forward."

    Therefore, whether the forward succeeds or not, you'll never be able to successfully send content back to the user both before and after a forward. This is because the purpose of a forward is to allow "one servlet to do preliminary processing of a request and another resource to generate the response", not to let two different servlets generate different parts of the response. In the Servlet model, generating a response always belongs to exactly one servlet.

    If you don't know what "committed" and "uncommitted" means, it's referring to whether the response status and headers have been sent to the user yet. When you're writing a response, you're actually writing into a local buffer. Nothing will necessarily be sent immediately. As long as everything you've written is still local, you're free to do whatever, including resetting the buffer and starting over, like a forward does, but as soon as something is sent off, you're committed and can no longer change what you were going to do. A response can become committed (i.e. be all or partly sent to the user) in a few ways, including filling up the buffer so that it has to be sent to make room for more content, flushing the buffer manually, or flushing the Writer or OutputStream of a response.

    Ultimately, what's probably happening in your case is that you're writing some stuff using an include, and it's causing the response to be committed, either because you've filled the buffer or because I seem to recall that an include generally causes an automatic flush (not sure about documentation on this one). Then when you try to forward, it's throwing the required IllegalStateException, which you should probably see in your logs somewhere, but won't cause the typical 500 response status since, as I've discussed, you've already committed with some other status code.