RequestDispatcher - when is a response committed?
Asked Answered
C

3

7

I'm writing some basic code as I learn about the RequestDispatcher. I understand that when rd.forward() is called, control (and response handling) is forwarded to the resource named in the path - in this case another servlet. But why doesn't this code throw an IllegalStateException (not that I want one) due to the out.write() statements earlier in the code?

I guess what I'm really asking is, how or when would these out.write() statements be committed?

Thanks, Jeff

public class Dispatcher extends HttpServlet{
  public void doGet(HttpServletRequest request, HttpServletResponse response)
           throws IOException, ServletException{

    response.setContentType("text/plain");
    PrintWriter out = response.getWriter();
    out.write("In Dispatcher\n");

    String modeParam = request.getParameter("mode");
    String path = "/Receiver/pathInfo?fruit=orange";
    RequestDispatcher rd = request.getRequestDispatcher(path);
    if(rd == null){
        out.write("Request Dispatcher is null. Please check path.");
    }
        if(modeParam.equals("forward")){
            out.write("forwarding...\n");
            rd.forward(request, response);
        }
        else if(modeParam.equals("include")){
            out.write("including...\n");
            rd.include(request, response);
        }
    out.flush();
    out.close();
}

}

Clockwise answered 14/8, 2013 at 9:19 Comment(0)
S
4

Because you haven't called flush.

Everything will be cleared out before forwarding if you haven't flushed. Otherwise, you'll get an excpetion you expect.

As in the docs:

For a RequestDispatcher obtained via getRequestDispatcher(), the ServletRequest object has its path elements and parameters adjusted to match the path of the target resource.

forward should be called before the response has been committed to the client (before response body output has been flushed). If the response already has been committed, this method throws an IllegalStateException. Uncommitted output in the response buffer is automatically cleared before the forward.

Stanzel answered 14/8, 2013 at 9:25 Comment(0)
G
3

Read the docs.

Calling flush() on the PrintWriter commits the response.

Now, as per your curiosity that why there is no IllegalStateException thrown. It's simply because PrintWriter.flush() doesn't throw this or any checked exception. And, we know that the response was not committed when rd.forward() is invoked, since flush() comes later in the method.

Graner answered 14/8, 2013 at 9:33 Comment(3)
Got it. Why, then, is no exception thrown if I modify the end of the code as follows: out.flush(); out.write("exception code?"); out.close();Clockwise
Exception is thrown in forward method if flush was called before thatStanzel
Precisely. Thanks, Tala. And don't forget everything has already been cleared, when it gets forwarded. See, Tala's post.Graner
J
1

You did not make call to flush() before forward. So it does not shows any exception. If you write flush() before request is forwarded then it will throw exception.

When We call flush(), then all what was in buffer is sent to the browser and buffer is cleared.

In following scenario we will get exception.

response.getWriter().print('hello...');  
response.getWriter().flush();  
request.getRequestDispatcher("/index.").forward(request, response);
Jamarjamb answered 14/8, 2013 at 9:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.