RequestDispatcher — когда фиксируется ответ?

Я пишу базовый код, когда узнаю о RequestDispatcher. Я понимаю, что при вызове rd.forward() управление (и обработка ответов) перенаправляется на ресурс, указанный в пути — в данном случае на другой сервлет. Но почему этот код не генерирует исключение IllegalStateException (не то, чтобы я этого хотел) из-за операторов out.write() ранее в коде?

Я думаю, что я действительно спрашиваю, как или когда эти операторы 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();
}

}


person Jeff Levine    schedule 14.08.2013    source источник


Ответы (3)


Потому что вы не позвонили flush.

Все будет очищено перед пересылкой, если вы не сбросили. В противном случае вы получите ожидаемое исключение.

Как и в документы:

Для RequestDispatcher, полученного с помощью getRequestDispatcher(), объект ServletRequest имеет элементы пути и параметры, скорректированные в соответствии с путем целевого ресурса.

forward следует вызывать до того, как ответ будет передан клиенту (до того, как вывод тела ответа будет очищен). Если ответ уже был зафиксирован, этот метод создает исключение IllegalStateException. Незафиксированный вывод в буфере ответов автоматически очищается перед пересылкой.

person Tala    schedule 14.08.2013

Прочтите документацию.

Вызов flush() на PrintWriter фиксирует ответ.

Теперь, согласно вашему любопытству, почему нет IllegalStateException. Это просто потому, что PrintWriter.flush() не выдает это или любое проверенное исключение. И мы знаем, что ответ не был зафиксирован при вызове rd.forward(), поскольку flush() появляется позже в методе.

person Adeel Ansari    schedule 14.08.2013
comment
Понятно. Почему же тогда не генерируется исключение, если я изменяю конец кода следующим образом: out.flush(); out.write("exception code?"); out.close(); - person Jeff Levine; 14.08.2013
comment
Исключение выдается в методе forward, если перед этим был вызван метод flush - person Tala; 14.08.2013
comment
Точно. Спасибо, Тала. И не забывайте, что все уже было очищено, когда оно будет отправлено. Смотрите, пост Талы. - person Adeel Ansari; 14.08.2013

Вы не сделали вызов flush() перед пересылкой. Таким образом, он не показывает никаких исключений. Если вы напишете flush() до того, как запрос будет перенаправлен, он вызовет исключение.

Когда мы вызываем flush(), то все, что было в буфере, отправляется в браузер и буфер очищается.

В следующем сценарии мы получим исключение.

response.getWriter().print('hello...');  
response.getWriter().flush();  
request.getRequestDispatcher("/index.").forward(request, response);
person Balakrishna    schedule 14.08.2013