RequestDispatcher.forward() против HttpServletResponse.sendRedirect()
В чем концептуальная разница между forward()
а также sendRedirect()
?
8 ответов
requestDispatcher - метод forward()
Когда мы используем метод forward, запрос передается другому ресурсу на том же сервере для дальнейшей обработки.
В случае пересылки, веб-контейнер обрабатывает все процессы внутренне, и клиент или браузер не задействованы.
Когда forward вызывается для объекта requestdispatcher, мы передаем объекты request и response, чтобы наш старый объект request присутствовал на новом ресурсе, который будет обрабатывать наш запрос.
Визуально мы не можем видеть перенаправленный адрес, он прозрачный.
Использование метода forward() быстрее, чем перенаправление send.
Когда мы перенаправляем с использованием forward и хотим использовать те же данные в новом ресурсе, мы можем использовать request.setAttribute (), так как у нас есть объект request.
SendRedirect
В случае sendRedirect запрос передается на другой ресурс в другой домен или на другой сервер для дальнейшей обработки.
Когда вы используете sendRedirect, контейнер передает запрос клиенту или браузеру, поэтому URL-адрес, указанный в методе sendRedirect, отображается как новый запрос для клиента.
В случае вызова sendRedirect старые объекты запроса и ответа теряются, поскольку браузер воспринимает их как новый запрос.
В адресной строке мы можем видеть новый перенаправленный адрес. Это не прозрачно.
sendRedirect медленнее, потому что требуется одно дополнительное обращение, потому что создается совершенно новый запрос и старый объект запроса теряется. Требуется два запроса браузера.
Но в sendRedirect, если мы хотим использовать, мы должны хранить данные в сеансе или передавать вместе с URL.
Какой из них хорош?
Это зависит от сценария, который метод является более полезным.
Если вы хотите, чтобы управление было перенесено на новый сервер или в контекст, и это рассматривается как совершенно новая задача, тогда мы переходим к переадресации. Как правило, следует использовать пересылку, если операция может быть безопасно повторена после перезагрузки веб-страницы в браузере, что не повлияет на результат.
Прежде всего, термин "перенаправление" - это в мире веб-разработки действие отправки клиенту пустого 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 в адресной строке браузера остается неизменным.
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
образец
RequestDispatcher
Интерфейс позволяет делать серверную сторону вперед / включить, тогда как sendRedirect()
выполняет перенаправление на стороне клиента. При перенаправлении на стороне клиента сервер отправит обратно HTTP-код состояния 302
(временное перенаправление), которое заставляет веб-браузер выдавать новый HTTP GET
запросить содержимое в перенаправленном местоположении. Напротив, при использовании RequestDispatcher
Интерфейс, включение / пересылка в новый ресурс полностью обрабатывается на стороне сервера.
Основное важное различие между методом forward () и sendRedirect() состоит в том, что в случае forward () перенаправление происходит на конце сервера и невидимо для клиента, но в случае sendRedirect() перенаправление происходит на стороне клиента и становится видимым клиенту.
Любой из этих методов может быть "лучше", то есть более подходящим, в зависимости от того, что вы хотите сделать.
Перенаправление на стороне сервера происходит быстрее, поскольку вы получаете данные с другой страницы, не обращаясь к браузеру. Но URL-адрес, видимый в браузере, по-прежнему является исходным адресом, поэтому вы создаете небольшое несоответствие.
Перенаправление на стороне клиента является более универсальным, поскольку оно может отправить вас на совершенно другой сервер или изменить протокол (например, с HTTP на HTTPS), или и то, и другое. И браузер знает о новом URL. Но это требует дополнительной перемотки между сервером и клиентом.
SendRedirect()
будет искать контент между серверами. это медленно, потому что он должен закрыть браузер, отправив URL-адрес содержимого. затем браузер создаст новый запрос контента на том же сервере или на другом.
RquestDispatcher
Я думаю, что для поиска контента на сервере. это процесс на стороне сервера, и это быстрее по сравнению с SendRedirect()
метод. но дело в том, что он не будет информировать браузер, на каком сервере он ищет требуемую дату или контент, и не будет просить браузер изменить URL-адрес на вкладке URL. так что это доставляет мало неудобств пользователю.
Технически перенаправление следует использовать либо в том случае, если нам нужно перенести управление в другой домен, либо для разделения задач.
Например, в платежном приложении мы сначала выполняем PaymentProcess, а затем перенаправляем на displayPaymentInfo. Если клиент обновляет браузер, только displayPaymentInfo будет выполнен снова, а PaymentProcess повторяться не будет. Но если мы будем использовать пересылку в этом сценарии, и PaymentProcess, и displayPaymentInfo будут выполняться повторно последовательно, что может привести к появлению недостоверных данных.
Для других сценариев форвард эффективен в использовании, так как он быстрее, чем sendRedirect.
Диспетчер запросов - это интерфейс, который используется для отправки запроса или ответа от веб-ресурса на другой веб-ресурс. Он содержит в основном два метода.
request.forward(req,res)
: Этот метод используется для пересылки запроса с одного веб-ресурса на другой ресурс. то есть от одного сервлета к другому сервлету или от одного веб-приложения к другому веб-приложению.response.include(req,res)
: Этот метод включает в себя ответ одного сервлета на другой сервлет
ПРИМЕЧАНИЕ. С помощью диспетчера запросов мы можем пересылать или включать запрос или ответы на одном сервере.
request.sendRedirect()
Используя это, мы можем пересылать или включать запросы или ответы на разные серверы. При этом клиент получает указание при перенаправлении страницы, но в вышеописанном процессе клиент не получит указание
Диспетчер позволяет передавать данные запроса из одного сервлета в другой сервлет. Альтернативой диспетчера запросов является перенаправление отправки, но при каждом новом запросе перенаправление отправки возвращается в сеть, если в сервере происходит обратный диспетчер запросов.
пример
Диспетчер сервлетов в Java Давайте разберемся с концепцией диспетчера запросов на простом примере. Рассмотрим ситуацию, когда у нас есть три сервлета, названных как servlet1,servlet2 и Servlet3. В случае, если мы не используем диспетчер, всякий раз, когда мы запрашиваем сервлет1, сервер передает управление сервлету1, после этого, если мы запрашиваем сервлет2, управление возвращается из сервлета 1 на сервер и передается сервлету2. В этом случае, если сервер находится в Индии и сервлет запрашивается из Америки, для второго запроса он должен вернуться на сервер (Индия) и вернуться в сервлет (Америка). Этот вариант не годится, если между запросом и ответом интенсивный трафик. Решением этой проблемы является диспетчер.
Диспетчер сервлетов в Java В том же случае, если мы используем диспетчер внутри сервера, управление передается из сервлета1 в сервлет2 без возврата на сервер и без участия сети. Эта концепция также называется цепочкой сервлетов. Это называется цепочкой сервлетов, потому что мы создаем цепочку запросов сервлетов, от сервлета1 к сервлету2, сервлета2 к сервлету3, и сервер будет получать данные из сервлета3.
Передача данных
В цепочке сервлетов не только передается управление, но и данные передаются от одного сервлета к другому сервлету, что является основным преимуществом по сравнению с перенаправлением отправки. В перенаправлении отправки каждый запрос является новым запросом, каждый раз, когда вы получаете новые данные.
Предположим, что сервлет1 имеет некоторый параметр запроса, который должен быть выполнен сервлетом3, тогда данные могут перемещаться из сервлета1 в сервлет2, а затем из сервлета2 в сервлет3, поэтому здесь мы сохраняем запрос от одного сервлета к другому сервлету.
Срок действия запроса очень мал, как только мы получаем ответ, запрос заканчивается, но здесь срок действия запроса можно сохранить от одного сервлета к другому. С помощью этого мы можем разделить задачу на множество сервлетов.
Недостаток
Диспетчер в большинстве случаев работает эффективно, но в случае больших данных или если нам вообще не нужны данные или в случае низкого трафика, отправьте работу перенаправления эффективно.
Просто разница между Forward(ServletRequest request, ServletResponse response)
а также sendRedirect(String url)
является
вперед():
forward()
Метод выполняется на стороне сервера.- Запрос переносится на другой ресурс внутри того же сервера.
- Это не зависит от протокола запроса клиента, так как
forward ()
Метод предоставляется контейнером сервлетов. - Запрос разделяется целевым ресурсом.
- В этом методе используется только один вызов.
- Это может быть использовано внутри сервера.
- Мы не можем видеть перенаправленное сообщение, оно прозрачное.
forward()
метод быстрее чемsendRedirect()
метод.- Объявлено в
RequestDispatcher
интерфейс.
sendRedirect():
- Метод sendRedirect() выполняется на стороне клиента.
- Запрос переносится на другой ресурс на другой сервер.
- Метод sendRedirect() предоставляется в разделе HTTP, поэтому его можно использовать только с клиентами HTTP.
- Новый запрос создан для ресурса назначения.
- Два запроса и ответных вызовов потребляются.
- Может использоваться внутри и за пределами сервера.
- Мы видим перенаправленный адрес, он не прозрачен.
- Метод sendRedirect() медленнее, потому что при создании нового запроса старый объект запроса теряется.
- Это объявлено в HttpServletResponse.