Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RequestDispatcher - when is a response committed?

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();
}

}

like image 377
Jeff Levine Avatar asked Aug 14 '13 09:08

Jeff Levine


2 Answers

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.

like image 157
Tala Avatar answered Sep 19 '22 22:09

Tala


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.

like image 28
Adeel Ansari Avatar answered Sep 21 '22 22:09

Adeel Ansari