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


Відповіді:


106

requestDispatcher - метод переходу ()

  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папку і використовувати a, 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успіх 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.
}

Таким чином, переадресація вказує клієнту GETнадіслати новий запит за вказаною URL-адресою. Оновлення запиту тоді оновить лише перенаправлений запит, а не початковий. Це дозволить уникнути "подвійних подань" та плутанини та поганого досвіду користувача. Це також називається POST-Redirect-GETвізерунком .

Дивитися також:


Коли я переадресовую сервлет на сторінку jsp, сторінка jsp частково завантажується, як у stackoverflow.com/questions/12337624/… . Я хотів, щоб перше, що було запущено, коли хто потрапив на foo.com, був сервлетом. З сервлета я роблю на response.sendRedirect("..")сторінку index.jsp веб-сайту. Але це пропускає файли css та деякий текст зі сторінки jsp, що призводить до часткового завантаження сторінки. Але коли я роблю, щоб привітальна сторінка веб-сайту була index.jsp, все працює нормально і завантаження сторінок завершено. що не так з перенаправленням?
саджанецьPro

20

RequestDispatcherІнтерфейс дозволяє виконувати на стороні сервера вперед / включають в той час як sendRedirect()робить на стороні клієнта перенаправлення. У випадку переадресації на стороні клієнта сервер відправить назад код статусу HTTP 302(тимчасове переадресація), через який веб-браузер видає абсолютно новий HTTP- GETзапит на вміст у перенаправленому місці. На відміну від цього, при використанні RequestDispatcherінтерфейсу включення / пересилання на новий ресурс обробляється повністю на стороні сервера.


І останнє насправді forward, а не перенаправлення.
Адель Ансарі

5

Основна важлива відмінність між методом forward () та sendRedirect () полягає в тому, що у випадку forward () перенаправлення відбувається на кінці сервера і не видно клієнтові, але у випадку sendRedirect () перенаправлення відбувається на кінці клієнта, і це видно клієнту.

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


2
Картина варта тисячі слів :)
Євген Лабун

4

Будь-який із цих методів може бути "кращим", тобто більш підходящим, залежно від того, що ви хочете зробити.

Перенаправлення на сторону сервера відбувається швидше, наскільки ви отримуєте дані з іншої сторінки, не здійснюючи зворотну поїздку до браузера. Але URL-адреса, переглянута у веб-переглядачі, все ще є оригінальною адресою, тому ви створюєте там трохи непослідовність.

Перенаправлення на стороні клієнта є більш універсальним, оскільки воно може відправити вас на зовсім інший сервер, або змінити протокол (наприклад, з HTTP на HTTPS), або на обидва. І браузер знає про нову URL-адресу. Але це вимагає додаткового зворотного руху між сервером і клієнтом.


2
Цей сегмент тут недостатньо згадується в Інтернеті: "або зміни протоколу (наприклад, з HTTP на HTTPS) або обох"
Perdomoff

3

SendRedirect()буде шукати вміст між серверами. це повільно, оскільки він повинен інтимувати браузер, надсилаючи URL-адресу вмісту. тоді браузер створить новий запит на вміст на тому ж сервері або на іншому.

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


1

Технічно переадресацію слід використовувати, або якщо нам потрібно перенести управління в інший домен, або досягти розділення завдання.

Наприклад, у програмі платежів ми спочатку робимо PaymentProcess, а потім перенаправляємо на displayPaymentInfo. Якщо клієнт оновить веб-переглядач, знову буде виконано displayPaymentInfo, і PaymentProcess не повториться. Але якщо ми будемо використовувати в цьому сценарії вперед, і 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. The 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.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.