RequestDispatcher.forward () vs HttpServletResponse.sendRedirect()
в чем принципиальная разница между forward()
и sendRedirect()
?
8 ответов:
requestDispatcher-forward () метод
когда мы используем метод forward, запрос передается на другой ресурс на том же сервере для дальнейшей обработки.
в случае переадресации веб-контейнер обрабатывает весь процесс внутри, а клиент или браузер не участвуют.
когда forward вызывается на объект requestdispatcher, мы передаем объекты запроса и ответа, поэтому наш старый объект запроса присутствует на новом ресурсе, который собирается обработать наш запрос.
визуально мы не можем видеть переадресованный адрес, он прозрачен.
С помощью метода forward () быстрее, чем отправить перенаправление.
когда мы перенаправляем с помощью forward и мы хотим использовать те же данные в новом ресурсе, мы можем использовать запрос.setAttribute (), поскольку у нас есть объект запроса.
SendRedirect
в случае sendRedirect, запрос передается на другой ресурс в другой домен или другой сервер для дальнейшей обработки.
при использовании sendRedirect контейнер передает запрос клиенту или браузеру, поэтому URL-адрес, указанный внутри метода sendRedirect, отображается как новый запрос клиенту.
в случае вызова sendRedirect старые объекты запроса и ответа теряются, поскольку они рассматриваются как новые запрос от браузера.
в адресной строке мы можем видеть новый перенаправленный адрес. Это не прозрачно.
sendRedirect работает медленнее, потому что требуется один дополнительный рейс туда и обратно, потому что создается совершенно новый запрос и старый объект запроса теряется. Требуется два запроса браузера.
но в sendRedirect, если мы хотим использовать, мы должны хранить данные в сессии или пройти вместе с URL-АДРЕС.
какой хороший?
Это зависит от сценария, какой метод более полезен.
если вы хотите, чтобы контроль был перенесен на новый сервер или контекст, и он рассматривается как совершенно новая задача, тогда мы идем на перенаправление отправки. Как правило, forward следует использовать, если операция может быть безопасно повторена после перезагрузки браузера веб-страницы не повлияет на результат.
прежде всего, термин "перенаправление" в мире веб-разработки-это действие отправки клиенту пустого HTTP-ответа только с
Location
заголовок с новым URL-адресом, по которому клиент должен отправить новый запрос GET. Так что в основном:
- клиент отправляет HTTP-запрос
some.jsp
.- сервер отправляет ответ HTTP с
Location: other.jsp
заголовок- клиент отправляет HTTP-запрос
other.jsp
(это отражается в адресной строке браузера бар!)- сервер отправляет ответ HTTP обратно с содержимым
other.jsp
.вы можете отслеживать его с помощью встроенного набора инструментов разработчика WebBrowser/addon. Нажмите F12 в Chrome/IE9 / Firebug и проверьте раздел "Сеть", чтобы увидеть его.
именно это достигается с помощью
sendRedirect("other.jsp")
. ЭлементRequestDispatcher#forward()
не отправляет редирект. Вместо этого он использует содержимое целевой страницы в качестве ответа HTTP.
- клиент отправляет HTTP-запрос
some.jsp
.- сервер отправляет ответ HTTP обратно с содержимым
other.jsp
.однако, поскольку исходный HTTP-запрос был
some.jsp
URL-адрес в адресной строке браузера остается неизменным.
The
RequestDispatcher
чрезвычайно полезно в парадигме MVC и / или когда вы хотите скрыть JSP от прямого доступа. Вы можете поместить JSP в/WEB-INF
папка и использоватьServlet
который управляет, выполняет предварительную обработку и postprocesses запросы. Разработки в/WEB-INF
папка не доступна напрямую по URL, ноServlet
можно получить доступ к ним с помощьюRequestDispatcher#forward()
.вы можете, например, иметь файл JSP в
/WEB-INF/login.jsp
иLoginServlet
, который назначен наurl-pattern
на/login
. Когда вы вызываетеhttp://example.com/context/login
, тогда сервлетаdoGet()
будет вызываться. Вы можете сделать любой pre обработка материала там и, наконец,вперед запрос типа:request.getRequestDispatcher("/WEB-INF/login.jsp").forward(request, response);
когда вы отправляете форму, вы обычно хотите используйте
POST
:<form action="login" method="post">
таким образом сервлет
doPost()
будет вызван и вы можете сделать любой postобработка материала там (например, проверка, бизнес-логика, вход пользователя и т. д.).если есть какие-либо ошибки, то вы хотите вперед запрос обратно на ту же страницу и отобразить ошибки там рядом с полями ввода и так далее. Вы можете использовать
RequestDispatcher
для этого.если a это успешно, вы обычно хотите редирект запрос, чтобы запрос не был повторно отправлен, когда пользователь обновит запрос (например, нажав 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. }
A редирект таким образом дает указание клиенту запустить новый
GET
запрос по заданному URL. Обновление запроса будет тогда обновлять только перенаправленный запрос, а не первоначальный запрос. Это позволит избежать "двойной отправки" и путаницы и плохого пользователя опыт. Это также называетсяPOST-Redirect-GET
pattern.
The
RequestDispatcher
интерфейс позволяет сделать серверную сторону вперед / включить тогда какsendRedirect()
делает перенаправление на стороне клиента. В перенаправлении на стороне клиента сервер отправит обратно код состояния HTTP302
(временное перенаправление), которое заставляет веб-браузер выдавать совершенно новый HTTPGET
запрос содержимого в перенаправленном месте. Напротив, при использованииRequestDispatcher
интерфейс, include/forward к новому ресурсу обрабатывается полностью на стороне сервера.
любой из этих методов может быть "лучше", т. е. более подходящий, в зависимости от того, что вы хотите сделать.
перенаправление на стороне сервера происходит быстрее, если вы получаете данные с другой страницы, не совершая туда и обратно в браузер. Но URL-адрес, видимый в браузере, по-прежнему является исходным адресом, поэтому вы создаете там небольшую несогласованность.
перенаправление на стороне клиента является более универсальным, поскольку оно может отправить вас на совершенно другой сервер или изменить протокол (например, от HTTP до HTTPS), или оба. И браузер знает о новом URL. Но это занимает дополнительное время между сервером и клиентом.
SendRedirect()
будет искать содержимое между серверами. это медленно, потому что он должен интимный браузер, отправив URL-адрес контента. затем браузер создаст новый запрос на контент внутри того же сервера или в другом.
RquestDispatcher
- для поиска контента на сервере, я думаю. его процесс на стороне сервера, и это быстрее по сравнению сSendRedirect()
метод. но дело в том, что это не будет интимный браузер, в котором сервер он ищет нужную дату или контент, ни его не задать в браузере, чтобы изменить URL-адрес в разделе URL-адрес. так что это вызывает мало неудобств для пользователя.
диспетчер запросов-это интерфейс, который используется для отправки запроса или ответа с веб-ресурса на другой веб-ресурс. Он содержит в основном два метода.
request.forward(req,res)
: этот метод используется для пересылки запроса с одного веб-ресурса на другой ресурс. т. е. от одного сервлета к другому сервлету или от одного веб-приложения к другому веб-приложению.
response.include(req,res)
: этот метод используется включить ответ одного сервлета к другому сервлетупримечание: с помощью Диспетчера запросов мы можем переслать или включить запрос или ответы С в том же сервере.
request.sendRedirect()
: С помощью этого мы можем пересылать или включать запрос или ответы на разных серверах. В этом клиент получает намек при перенаправлении страницы, но в приведенном выше процессе клиент не получит намек
технически редирект должен использоваться либо при необходимости передачи управления в другой домен, либо для достижения разделения задачи.
например, в платежном приложении сначала мы делаем PaymentProcess, а затем перенаправляем на displayPaymentInfo. Если клиент обновляет браузер только displayPaymentInfo будет сделано снова и PaymentProcess не будет повторяться. Но если мы используем forward в этом сценарии, оба PaymentProcess и displayPaymentInfo будут повторно выполнены последовательно, что может привести к несогласованным данным.
для других сценариев forward эффективно использовать, так как он быстрее, чем sendRedirect