RequestDispatcher.forward () против HttpServletResponse.sendRedirect ()

Ответы:

106

requestDispatcher - метод forward ()

  1. Когда мы используем этот forwardметод, запрос передается другому ресурсу на том же сервере для дальнейшей обработки.

  2. В случае forward, веб-контейнер обрабатывает всю внутреннюю обработку, а клиент или браузер не задействованы.

  3. Когда forwardвызывается requestDispatcherобъект, мы передаем объекты запроса и ответа, поэтому наш старый объект запроса присутствует на новом ресурсе, который будет обрабатывать наш запрос.

  4. Визуально мы не видим переадресованный адрес, он прозрачен.

  5. Использование forward()метода быстрее, чем sendRedirect.

  6. Когда мы перенаправляем с помощью переадресации и хотим использовать те же данные в новом ресурсе, мы можем использовать их, request.setAttribute()поскольку у нас есть доступный объект запроса.

SendRedirect

  1. В случае sendRedirect, запрос передается на другой ресурс, в другой домен или на другой сервер для дальнейшей обработки.

  2. Когда вы используете sendRedirect, контейнер передает запрос клиенту или браузеру, поэтому URL, указанный внутри sendRedirectметода, виден как новый запрос для клиента.

  3. В случае sendRedirectвызова старые объекты запроса и ответа теряются, поскольку браузер обрабатывает их как новый запрос.

  4. В адресной строке мы видим новый перенаправленный адрес. Это не прозрачно.

  5. sendRedirectмедленнее, потому что требуется один дополнительный круговой обход, поскольку создается совершенно новый запрос, а старый объект запроса теряется. Требуются два запроса браузера.

  6. Но sendRedirectесли мы хотим использовать те же данные для нового ресурса, мы должны хранить данные в сеансе или передавать вместе с URL-адресом.

Какой из них хороший?

Это зависит от сценария, для которого метод более полезен.

Если вы хотите, чтобы управление было передано новому серверу или контексту, и это рассматривается как совершенно новая задача, тогда мы идем sendRedirect. Как правило, следует использовать переадресацию, если операцию можно безопасно повторить при перезагрузке веб-страницы браузером и это не повлияет на результат.

Источник

Абхиджит Ашок Мунешвар
источник
161

В мире веб-разработки термин «перенаправление» - это отправка клиенту пустого HTTP-ответа с Locationзаголовком, содержащим новый URL-адрес, на который клиент должен отправить новый запрос GET. Итак, в основном:

  • Клиент отправляет HTTP-запрос в some.jsp.
  • Сервер отправляет ответ HTTP с Location: other.jspзаголовком
  • Клиент отправляет HTTP-запрос other.jsp(это отображается в адресной строке браузера!)
  • Сервер отправляет ответ HTTP с содержимым other.jsp.

Вы можете отслеживать его с помощью встроенного набора инструментов разработчика / надстройки веб-браузера. Нажмите F12 в Chrome / IE9 / Firebug и проверьте раздел «Сеть», чтобы увидеть его.

Именно это достигается с помощью sendRedirect("other.jsp"). RequestDispatcher#forward()Не посылает редирект. Вместо этого он использует содержимое целевой страницы как HTTP-ответ.

  • Клиент отправляет HTTP-запрос в some.jsp.
  • Сервер отправляет ответ HTTP с содержимым other.jsp.

Однако, поскольку исходный HTTP-запрос должен был some.jsp , URL-адрес в адресной строке браузера остается неизменным. Кроме того, любые атрибуты запроса, установленные в контроллере позади, some.jspбудут доступны в other.jsp. Этого не происходит во время перенаправления, потому что вы в основном заставляете клиента создавать новый HTTP-запрос other.jsp, тем самым отбрасывая исходный запрос, some.jspвключая все его атрибуты.


RequestDispatcher чрезвычайно полезно в парадигме MVC и / или когда вы хотите скрыть JSP от прямого доступа. Вы можете поместить JSP в /WEB-INFпапку и использовать для Servletуправления, предварительной и постобработки запросов. JSP в /WEB-INFпапке недоступны напрямую по URL-адресу, но они Servletмогут получить к ним доступ с помощью RequestDispatcher#forward().

Вы можете, например , иметь файл JSP в /WEB-INF/login.jspи , LoginServletкоторый преобразуется по принципу url-patternиз /login. При вызове http://example.com/context/loginсервлетаdoGet() будет вызван . Вы можете выполнить любую предварительную обработку и, наконец, отправить запрос, например:

request.getRequestDispatcher("/WEB-INF/login.jsp").forward(request, response);

Когда вы отправляете форму, вы обычно хотите использовать POST:

<form action="login" method="post">

Таким образом, сервлет doPost()будет вызван, и вы сможете выполнять там любую пост- обработку (например, проверку, бизнес-логику, вход пользователя в систему и т. Д.).

Если есть какие-либо ошибки, вы обычно хотите перенаправить запрос обратно на ту же страницу и отобразить ошибки там рядом с полями ввода и так далее. Вы можете использовать RequestDispatcherдля этого.

В случае POSTуспеха вы обычно хотите перенаправить запрос, чтобы запрос не отправлялся повторно, когда пользователь обновляет запрос (например, нажатие F5 или переход назад в истории).

User user = userDAO.find(username, password);
if (user != null) {
    request.getSession().setAttribute("user", user); // Login user.
    response.sendRedirect("home"); // Redirects to http://example.com/context/home after succesful login.
} else {
    request.setAttribute("error", "Unknown login, please try again."); // Set error.
    request.getRequestDispatcher("/WEB-INF/login.jsp").forward(request, response); // Forward to same page so that you can display error.
}

Редирект таким образом , указывает клиенту сгореть новыйGET запрос по данному URL. При обновлении запроса будет обновлен только перенаправленный запрос, а не первоначальный запрос. Это позволит избежать «двойных отправок», путаницы и неудобств для пользователей. Это также называется POST-Redirect-GETпаттерном .

Смотрите также:

BalusC
источник
Когда я перенаправляю с сервлета на страницу jsp, страница jsp загружается частично, как в stackoverflow.com/questions/12337624/… . Я хотел, чтобы первое, что запускалось при попадании на foo.com, было сервлетом. Из сервлета я response.sendRedirect("..")перехожу на страницу index.jsp веб-сайта. Но это пропускает файлы css и некоторый текст со страницы jsp, что приводит к частичной загрузке страницы. Но когда я делаю страницу приветствия сайта index.jsp, все работает нормально, и страница загружается. что не так с редиректом?
saplingPro
20

RequestDispatcherИнтерфейс позволяет выполнять на стороне сервера вперед / включают в то время как sendRedirect()делает на стороне клиента перенаправления. При перенаправлении на стороне клиента сервер отправляет обратно код состояния HTTP 302(временное перенаправление), что заставляет веб-браузер выдавать совершенно новый HTTP- GETзапрос для содержимого в перенаправленном месте. Напротив, при использовании RequestDispatcherинтерфейса включение / пересылка к новому ресурсу полностью выполняется на стороне сервера.

Асаф
источник
И последнее на самом деле forwardне перенаправление.
Adeel Ansari
5

Основное важное различие между методами forward () и sendRedirect () заключается в том, что в случае forward () перенаправление происходит на стороне сервера и не отображается для клиента, но в случае sendRedirect () перенаправление происходит на стороне клиента и оно видно. клиенту.

введите описание изображения здесь

Джоби Уилсон Мэтьюз
источник
2
Картинка стоит тысячи слов :)
Ойген Лабун
4

Любой из этих методов может быть «лучше», т.е. более подходящим, в зависимости от того, что вы хотите сделать.

Перенаправление на стороне сервера происходит быстрее, поскольку вы получаете данные с другой страницы, не обращаясь к браузеру. Но URL-адрес, отображаемый в браузере, по-прежнему является исходным адресом, поэтому вы создаете здесь небольшую несогласованность.

Перенаправление на стороне клиента более универсально, поскольку оно может отправить вас на совершенно другой сервер или изменить протокол (например, с HTTP на HTTPS) или и то, и другое. И браузер знает о новом URL. Но для этого требуется дополнительный обмен данными между сервером и клиентом.

Карл Смотрич
источник
2
Этот сегмент прямо здесь недостаточно упоминается в Интернете: «или измените протокол (например, с HTTP на HTTPS), или и то, и другое»
Perdomoff
3

SendRedirect()будет искать контент между серверами. это медленно, потому что он должен интимизировать браузер, отправляя URL-адрес контента. тогда браузер создаст новый запрос контента на том же сервере или на другом.

RquestDispatcherя думаю, для поиска контента на сервере. это процесс на стороне сервера, и он быстрее по сравнению с SendRedirect()методом. но дело в том, что он не будет указывать браузеру, на каком сервере он ищет требуемую дату или контент, а также не будет просить браузер изменить URL-адрес на вкладке URL. поэтому пользователю это не доставляет неудобств.

Rajagonda
источник
1

Технически редирект следует использовать либо в том случае, если нам нужно передать управление другому домену, либо для разделения задач.

Например, в платежном приложении мы сначала выполняем PaymentProcess, а затем перенаправляем на displayPaymentInfo. Если клиент обновляет браузер, только displayPaymentInfo будет выполнен снова, и PaymentProcess не будет повторяться. Но если мы используем в этом сценарии forward, как PaymentProcess, так и displayPaymentInfo будут повторно выполняться последовательно, что может привести к несостоятельности данных.

Для других сценариев переадресация эффективна, поскольку она быстрее, чем sendRedirect.

Рохит Гоял
источник
0

Диспетчер запросов - это интерфейс, который используется для отправки запроса или ответа от веб-ресурса другому веб-ресурсу. Он содержит в основном два метода.

  1. request.forward(req,res): Этот метод используется для пересылки запроса от одного веб-ресурса к другому ресурсу. т.е. от одного сервлета к другому сервлету или от одного веб-приложения к другому веб-приложению.

  2. response.include(req,res): Этот метод используется для включения ответа одного сервлета на другой сервлет.

ПРИМЕЧАНИЕ. Используя диспетчер запросов, мы можем пересылать или включать запрос или ответы на том же сервере.

request.sendRedirect(): Используя это, мы можем пересылать или включать запрос или ответы на разных серверах. В этом случае клиент получает указание при перенаправлении страницы, но в вышеуказанном процессе клиент не получит указание

Ашвин Патил
источник
-1

Просто разница между Forward(ServletRequest request, ServletResponse response)и sendRedirect(String url)есть

вперед():

  1. forward()Метод выполняется на стороне сервера.
  2. Запрос передается другому ресурсу на том же сервере.
  3. Это не зависит от протокола запроса клиента, поскольку forward ()метод предоставляется контейнером сервлета.
  4. Запрос разделяется целевым ресурсом.
  5. В этом методе используется только один вызов.
  6. Его можно использовать на сервере.
  7. Переадресованное сообщение не видно, оно прозрачное.
  8. forward()Метод быстрее , чем sendRedirect()метод.
  9. Это объявлено в RequestDispatcherинтерфейсе.

sendRedirect ():

  1. Метод sendRedirect () выполняется на стороне клиента.
  2. Запрос передается с другого ресурса на другой сервер.
  3. Метод sendRedirect () предоставляется по протоколу HTTP, поэтому его можно использовать только с HTTP-клиентами.
  4. Новый запрос создан для целевого ресурса.
  5. Используются два вызова запроса и ответа.
  6. Его можно использовать как на сервере, так и за его пределами.
  7. Мы видим перенаправленный адрес, он не прозрачный.
  8. Метод sendRedirect () работает медленнее, потому что при создании нового запроса старый объект запроса теряется.
  9. Он объявлен в HttpServletResponse.
Маулик Какадия
источник