RequestDispatcher.forward () kontra HttpServletResponse.sendRedirect ()

Odpowiedzi:

106

requestDispatcher - metoda forward ()

  1. Kiedy używamy tej forwardmetody, żądanie jest przesyłane do innego zasobu na tym samym serwerze w celu dalszego przetwarzania.

  2. W przypadku forwardkontenera WWW całe przetwarzanie obsługuje wewnętrznie, a klient ani przeglądarka nie są zaangażowani.

  3. Kiedy forwardjest wywoływany na requestDispatcherobiekcie, przekazujemy obiekty żądania i odpowiedzi, więc nasz stary obiekt żądania jest obecny w nowym zasobie, który będzie przetwarzał nasze żądanie.

  4. Wizualnie nie widzimy przekierowanego adresu, jest przejrzysty.

  5. Korzystanie z tej forward()metody jest szybsze niż sendRedirect.

  6. Kiedy przekierowujemy za pomocą forward i chcemy użyć tych samych danych w nowym zasobie, możemy użyć request.setAttribute()dostępnego obiektu żądania.

SendRedirect

  1. W przypadku sendRedirectżądania przesyłane jest do innego zasobu, do innej domeny lub do innego serwera w celu dalszego przetwarzania.

  2. Kiedy używasz sendRedirect, kontener przekazuje żądanie do klienta lub przeglądarki, więc adres URL podany w sendRedirectmetodzie jest widoczny jako nowe żądanie dla klienta.

  3. W przypadku sendRedirectwywołania stare obiekty żądań i odpowiedzi są tracone, ponieważ są one traktowane przez przeglądarkę jako nowe żądanie.

  4. Na pasku adresu możemy zobaczyć nowy przekierowany adres. To nie jest przejrzyste.

  5. sendRedirectjest wolniejszy, ponieważ wymagana jest jedna dodatkowa podróż w obie strony, ponieważ tworzone jest zupełnie nowe żądanie, a stary obiekt żądania zostaje utracony. Wymagane są dwa żądania przeglądarki.

  6. Ale sendRedirectjeśli chcemy użyć tych samych danych dla nowego zasobu, musimy je przechowywać w sesji lub przekazać wraz z adresem URL.

Który jest dobry?

Zależy to od scenariusza, w którym metoda jest bardziej użyteczna.

Jeśli chcesz, aby kontrola została przeniesiona na nowy serwer lub kontekst i jest traktowana jako zupełnie nowe zadanie, to idziemy sendRedirect. Ogólnie rzecz biorąc, należy użyć przekazywania dalej, jeśli operację można bezpiecznie powtórzyć po ponownym załadowaniu strony internetowej w przeglądarce i nie wpłynie to na wynik.

Źródło

Abhijeet Ashok Muneshwar
źródło
161

W świecie tworzenia stron internetowych termin „przekierowanie” oznacza wysłanie do klienta pustej odpowiedzi HTTP z tylko Locationnagłówkiem zawierającym nowy adres URL, do którego klient musi wysłać zupełnie nowe żądanie GET. Więc w zasadzie:

  • Klient wysyła żądanie HTTP do some.jsp.
  • Serwer odsyła odpowiedź HTTP z Location: other.jspnagłówkiem
  • Klient wysyła żądanie HTTP do other.jsp(jest to odzwierciedlone w pasku adresu przeglądarki!)
  • Serwer odsyła odpowiedź HTTP z zawartością pliku other.jsp.

Możesz go śledzić za pomocą wbudowanego / dodatkowego zestawu narzędzi programistycznych przeglądarki internetowej. Naciśnij klawisz F12 w przeglądarce Chrome / IE9 / Firebug i sprawdź sekcję „Sieć”, aby ją zobaczyć.

Dokładnie to osiąga sendRedirect("other.jsp"). RequestDispatcher#forward()Nie wysyła przekierowanie. Zamiast tego używa zawartości strony docelowej jako odpowiedzi HTTP.

  • Klient wysyła żądanie HTTP do some.jsp.
  • Serwer odsyła odpowiedź HTTP z zawartością pliku other.jsp.

Jednak zgodnie z pierwotnym żądaniem HTTP some.jspadres URL w pasku adresu przeglądarki pozostaje niezmieniony. Ponadto wszystkie atrybuty żądań ustawione w kontrolerze z tyłu some.jspbędą dostępne w other.jsp. Nie dzieje się tak podczas przekierowania, ponieważ w zasadzie zmuszasz klienta do utworzenia nowego żądania HTTP other.jsp, w ten sposób wyrzucając pierwotne żądanie, some.jspwłączając wszystkie jego atrybuty.


Jest RequestDispatcherto niezwykle przydatne w paradygmacie MVC i / lub gdy chcesz ukryć strony JSP przed bezpośrednim dostępem. Możesz umieścić strony JSP w /WEB-INFfolderze i użyć Servletkontrolki, która kontroluje, wstępnie przetwarza i postprocesuje żądania. Strony JSP w /WEB-INFfolderze nie są bezpośrednio dostępne przez adres URL, ale Servletmożna uzyskać do nich dostęp za pomocą RequestDispatcher#forward().

Można na przykład mieć plik JSP w /WEB-INF/login.jspa LoginServletktóra jest odwzorowywane na url-patternod /login. Po wywołaniu zostanie wywołany http://example.com/context/loginserwlet doGet(). Możesz tam wykonać dowolne czynności wstępne i na koniec przesłać żądanie, takie jak:

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

Przesyłając formularz, zwykle chcesz użyć POST:

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

W ten sposób serwlet doPost()zostanie wywołany i będziesz mógł tam wykonać dowolne czynności post- processingu (np. Walidacja, logika biznesowa, logowanie użytkownika itp.).

Jeśli są jakieś błędy, zwykle chcesz przekazać żądanie z powrotem na tę samą stronę i wyświetlić błędy tam obok pól wejściowych i tak dalej. Możesz użyć RequestDispatcherdo tego.

Jeśli operacja POSTsię powiedzie, zwykle chcesz przekierować żądanie, aby żądanie nie zostało przesłane ponownie, gdy użytkownik odświeży żądanie (np. Naciskając klawisz F5 lub przechodząc z powrotem do historii).

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.
}

W ten sposób przekierowanie instruuje klienta, aby uruchomił nowe GETżądanie pod podanym adresem URL. Odświeżenie żądania spowoduje wtedy tylko odświeżenie przekierowanego żądania, a nie pierwotnego żądania. Pozwoli to uniknąć „podwójnych zgłoszeń”, zamieszania i złych wrażeń użytkowników. Nazywa się to również POST-Redirect-GETwzorem .

Zobacz też:

BalusC
źródło
Kiedy przekierowuję z serwletu na stronę jsp, strona jsp jest częściowo ładowana, jak w stackoverflow.com/questions/12337624/… . Chciałem, aby pierwsza rzecz, która została uruchomiona, gdy ktoś trafi na foo.com, była serwletem . Z serwletu response.sendRedirect("..")przechodzę do strony index.jsp serwisu WWW. Ale to pomija pliki css i część tekstu ze strony jsp, co prowadzi do częściowego załadowania strony. Ale kiedy ustawię stronę powitalną witryny jako index.jsp, wszystko działa dobrze i strona ładuje się zakończona. co jest nie tak z przekierowaniem?
saplingPro
20

RequestDispatcherInterfejs pozwala zrobić po stronie serwera do przodu / include natomiast sendRedirect()robi przekierowanie po stronie klienta. W przypadku przekierowania po stronie klienta serwer odeśle kod statusu HTTP 302(przekierowanie tymczasowe), co powoduje, że przeglądarka internetowa wysyła zupełnie nowe GETżądanie HTTP dla treści w przekierowanej lokalizacji. Natomiast w przypadku korzystania z RequestDispatcherinterfejsu dołączanie / przesyłanie dalej do nowego zasobu jest obsługiwane całkowicie po stronie serwera.

Asaf
źródło
A to drugie w rzeczywistości forwardnie jest przekierowaniem.
Adeel Ansari,
5

Główną istotną różnicą między metodami forward () i sendRedirect () jest to, że w przypadku forward () przekierowanie następuje na końcu serwera i nie jest widoczne dla klienta, ale w przypadku sendRedirect (), przekierowanie następuje na końcu klienta i jest widoczne do klienta.

wprowadź opis obrazu tutaj

Joby Wilson Mathews
źródło
2
Obraz jest wart tysiąca słów :)
Eugen Labun
4

Każda z tych metod może być „lepsza”, tj. Bardziej odpowiednia, w zależności od tego, co chcesz zrobić.

Przekierowanie po stronie serwera jest szybsze, o ile otrzymujesz dane z innej strony bez przechodzenia w obie strony do przeglądarki. Ale adres URL widoczny w przeglądarce jest nadal pierwotnym adresem, więc tworzysz tam małą niespójność.

Przekierowanie po stronie klienta jest bardziej wszechstronne, ponieważ może wysłać Cię na zupełnie inny serwer, zmienić protokół (np. Z HTTP na HTTPS) lub jedno i drugie. Przeglądarka rozpoznaje nowy adres URL. Jednak między serwerem a klientem wymagana jest dodatkowa operacja.

Carl Smotricz
źródło
2
Ten segment jest niewystarczająco wspomniany w sieci: „lub zmień protokół (np. Z HTTP na HTTPS) lub oba”
Perdomoff,
3

SendRedirect()przeszuka zawartość między serwerami. jest powolny, ponieważ musi ingerować w przeglądarkę, wysyłając adres URL treści. przeglądarka utworzy nowe żądanie treści na tym samym lub innym serwerze.

RquestDispatcherjest do wyszukiwania treści na serwerze. jest to proces po stronie serwera i jest szybszy w porównaniu do SendRedirect()metody. ale chodzi o to, że nie będzie intymne z przeglądarką, w której serwerze szuka wymaganej daty lub treści, ani nie poprosi przeglądarki o zmianę adresu URL w zakładce URL. więc powoduje niewielkie niedogodności dla użytkownika.

Rajagonda
źródło
1

Z technicznego punktu widzenia przekierowanie powinno być używane albo wtedy, gdy musimy przenieść kontrolę do innej domeny, albo w celu uzyskania rozdzielenia zadań.

Na przykład w aplikacji płatniczej najpierw wykonujemy PaymentProcess, a następnie przekierowujemy do displayPaymentInfo. Jeśli klient odświeży przeglądarkę, tylko wyświetlenie informacji o płatnościach zostanie wykonane ponownie, a proces płatności nie zostanie powtórzony. Ale jeśli w tym scenariuszu użyjemy forward, zarówno PaymentProcess, jak i displayPaymentInfo zostaną ponownie wykonane sekwencyjnie, co może spowodować niespójność danych.

W innych scenariuszach forward jest efektywny w użyciu, ponieważ jest szybszy niż sendRedirect

Rohit Goyal
źródło
0

Dyspozytor żądań to interfejs używany do wysyłania żądania lub odpowiedzi z zasobu internetowego do innego zasobu sieciowego. Zawiera głównie dwie metody.

  1. request.forward(req,res): Ta metoda służy do przekazywania żądania z jednego zasobu sieciowego do innego zasobu. tj. z jednego serwletu do innego serwletu lub z jednej aplikacji internetowej do innej aplikacji internetowej.

  2. response.include(req,res): Ta metoda jest używana do uwzględniania odpowiedzi jednego serwletu na inny aplet

UWAGA: Korzystając z Request Dispatcher, możemy przekazać lub dołączyć żądanie lub odpowiedzi na tym samym serwerze.

request.sendRedirect(): Używając tego, możemy przekazać lub dołączyć żądanie lub odpowiedzi na różnych serwerach. W tym przypadku klient otrzymuje powiadomienie podczas przekierowywania strony, ale w powyższym procesie klient nie otrzyma powiadomienia

Ashwin Patil
źródło
-1

Po prostu różnica między Forward(ServletRequest request, ServletResponse response)i sendRedirect(String url)jest

Naprzód():

  1. forward()Metoda jest wykonywany po stronie serwera.
  2. Żądanie jest przesyłane do innego zasobu na tym samym serwerze.
  3. Nie zależy od protokołu żądania klienta, ponieważ forward ()metoda jest udostępniana przez kontener serwletów.
  4. Żądanie jest udostępniane przez zasób docelowy.
  5. W tej metodzie używane jest tylko jedno wywołanie.
  6. Może być używany na serwerze.
  7. Nie widzimy przekazanej wiadomości, jest ona przezroczysta.
  8. forward()Metoda jest szybsza niż sendRedirect()metody.
  9. Jest to zadeklarowane w RequestDispatcherinterfejsie.

sendRedirect ():

  1. Metoda sendRedirect () jest wykonywana po stronie klienta.
  2. Żądanie jest przesyłane do innego zasobu na inny serwer.
  3. Metoda sendRedirect () jest udostępniana w protokole HTTP, więc może być używana tylko z klientami HTTP.
  4. Zostanie utworzone nowe żądanie dla zasobu docelowego.
  5. Używane są dwa wywołania żądania i odpowiedzi.
  6. Może być używany na serwerze i poza nim.
  7. Widzimy przekierowany adres, nie jest przejrzysty.
  8. Metoda sendRedirect () jest wolniejsza, ponieważ po utworzeniu nowego żądania stary obiekt żądania jest tracony.
  9. Jest zadeklarowany w HttpServletResponse.
Maulik Kakadiya
źródło