7

当我了解 RequestDispatcher 时,我正在编写一些基本代码。我知道当调用 rd.forward() 时,控制(和响应处理)被转发到路径中指定的资源 - 在这种情况下是另一个 servlet。但是,由于代码前面的 out.write() 语句,为什么这段代码不抛出 IllegalStateException(不是我想要的)?

我想我真正要问的是,这些 out.write() 语句将如何或何时提交?

谢谢,杰夫

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

}

4

3 回答 3

4

因为你没有打电话flush

如果您还没有刷新,一切都会在转发之前被清除。否则,您将得到预期的结果。

文档中所示:

对于通过 getRequestDispatcher() 获得的 RequestDispatcher,ServletRequest 对象调整其路径元素和参数以匹配目标资源的路径。

forward 应该在响应提交给客户端之前调用(在刷新响应主体输出之前)。如果已提交响应,则此方法将引发 IllegalStateException。响应缓冲区中未提交的输出在转发之前会自动清除。

于 2013-08-14T09:25:22.133 回答
3

阅读文档

调用flush()提交PrintWriter响应。

现在,根据您的好奇心,为什么没有IllegalStateException抛出。这仅仅是因为PrintWriter.flush()不抛出这个或任何检查的异常。而且,我们知道响应在rd.forward()被调用时没有提交,因为flush()在方法的后面会出现。

于 2013-08-14T09:33:40.263 回答
1

您在转发之前没有调用flush()。所以它没有显示任何异常。如果你在请求被转发之前写flush(),那么它会抛出异常。

当我们调用 flush() 时,缓冲区中的所有内容都会发送到浏览器并清除缓冲区。

在以下情况下,我们将得到异常。

response.getWriter().print('hello...');  
response.getWriter().flush();  
request.getRequestDispatcher("/index.").forward(request, response);
于 2013-08-14T09:42:41.660 回答