RequestDispatcher.forward()とHttpServletResponse.sendRedirect()


回答:


106

requestDispatcher-forward()メソッド

  1. このforwardメソッドを使用すると、リクエストは同じサーバー内の別のリソースに転送され、さらに処理されます。

  2. の場合forward、Webコンテナはすべての処理を内部的に処理し、クライアントやブラウザは関与しません。

  3. ときforwardに呼び出されたrequestDispatcherオブジェクト私たちの古いリクエストオブジェクトは、私たちの要求を処理しようとしている新しいリソース上に存在しているので、我々は、リクエストとレスポンスオブジェクトを渡します。

  4. 視覚的に、転送されたアドレスを確認することはできません。それは透過的です。

  5. forward()メソッドを使用すると、よりも高速ですsendRedirect

  6. forwardを使用してリダイレクトし、同じデータを新しいリソースで使用request.setAttribute()したい場合は、リクエストオブジェクトを使用できるので使用できます。

SendRedirect

  1. の場合sendRedirect、リクエストは別のリソース、別のドメイン、または別のサーバーに転送され、さらに処理されます。

  2. を使用するsendRedirectと、コンテナがリクエストをクライアントまたはブラウザに転送するため、sendRedirectメソッド内で指定されたURL は、クライアントへの新しいリクエストとして表示されます。

  3. sendRedirect呼び出しの場合、古い要求と応答オブジェクトはブラウザによって新しい要求として扱われるため、失われます。

  4. アドレスバーに、リダイレクトされた新しいアドレスが表示されます。透明ではありません。

  5. sendRedirect完全に新しいリクエストが作成され、古いリクエストオブジェクトが失われるため、追加のラウンドトリップが1つ必要になるため、速度は遅くなります。2つのブラウザー要求が必要です。

  6. しかし、sendRedirectでは、同じデータを新しいリソースに使用する場合は、セッション中にデータを保存するか、URLとともに渡す必要があります。

どっちがいい?

これは、どの方法がより有用かというシナリオに依存します。

制御を新しいサーバーまたはコンテキストに転送する必要があり、それが完全に新しいタスクとして扱われる場合は、に進みsendRedirectます。一般に、ブラウザがWebページをリロードしたときに操作を安全に繰り返すことができ、結果に影響がない場合は、転送を使用する必要があります。

ソース


161

Web開発の世界では、「リダイレクト」という用語はLocation、クライアントが新しいGETリクエストを送信する必要がある新しいURLを含むヘッダーのみを含む空のHTTP応答をクライアントに送信する行為です。だから基本的に:

  • クライアントはHTTPリクエストをに送信しますsome.jsp
  • サーバーはLocation: other.jspヘッダー付きのHTTP応答を返します
  • クライアントはにHTTPリクエストを送信しますother.jsp(これはブラウザーのアドレスバーに反映されます!)
  • サーバーはのコンテンツを含むHTTP応答を返しますother.jsp

Webブラウザーの組み込み/アドオン開発者ツールセットで追跡できます。Chrome / IE9 / FirebugでF12を押し、[ネットワーク]セクションを確認してください。

正確に上記はによって達成され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、要求を制御、前処理、および後処理するを使用できます。/WEB-INFフォルダ内のJSPは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パターンとも呼ばれます

以下も参照してください。


サーブレットからjspページにリダイレクトすると、stackoverflow.com / questions / 12337624 / …のように、jspページが部分的に読み込まれます。誰もがfoo.comをヒットしたときに最初に実行されるものをサーブレットにしたかった。サーブレットから、response.sendRedirect("..")Webサイトのindex.jspページにアクセスします。ただし、CSSファイルとjspページの一部のテキストが欠落しているため、ページが部分的に読み込まれます。しかし、ウェブサイトのウェルカムページをindex.jspにすると、すべてが正常に機能し、ページの読み込みが完了します。リダイレクトの何が問題になっていますか?
saplingPro

20

このRequestDispatcherインターフェースでは、サーバー側のフォワード/インクルードを実行できますsendRedirect()が、クライアント側のリダイレクトは可能です。クライアント側のリダイレクトでは、サーバーは302(一時的なリダイレクト)のHTTPステータスコードを返します。これにより、WebブラウザーGETはリダイレクトされた場所のコンテンツに対してまったく新しいHTTP リクエストを発行します。対照的に、RequestDispatcherインターフェースを使用する場合、新しいリソースへのinclude / forwardは完全にサーバー側で処理されます。


そして後者はforwardリダイレクトではなく実際にです。
Adeel Ansari、2010

5

forward()メソッドとsendRedirect()メソッドの主な重要な違いは、forward()の場合、リダイレクトはサーバーエンドで発生し、クライアントには表示されませんが、sendRedirect()の場合、リダイレクトはクライアントエンドで発生し、表示されます。クライアントに。

ここに画像の説明を入力してください


2
写真は千の言葉に値します:)
Eugen Labun '26 / 11/18

4

これらの方法はどちらも、やりたいことに応じて、「より良い」、つまりより適切な場合があります。

ブラウザへの往復を行わずに別のページからデータを取得する限り、サーバー側のリダイレクトは高速です。ただし、ブラウザに表示されるURLは元のアドレスのままなので、そこで少し矛盾が生じます。

クライアント側のリダイレクトは、完全に異なるサーバーに送信したり、プロトコルを変更(HTTPからHTTPSなど)したり、あるいはその両方を実行したりできる限り、より用途が広いです。また、ブラウザは新しいURLを認識します。しかし、サーバーとクライアントの間で追加の往復が必要です。


2
このセグメントはWebでは十分に言及されていません。「またはプロトコルを変更する(たとえば、HTTPからHTTPSに)、またはその両方」
Perdomoff

3

SendRedirect()サーバー間のコンテンツを検索します。コンテンツのURLを送信してブラウザを親密化する必要があるため、処理が遅くなります。次に、ブラウザーは同じサーバーまたは別のサーバー内のコンテンツに対する新しい要求を作成します。

RquestDispatcher私が思うサーバー内のコンテンツを検索するためのものです。サーバー側のプロセスであり、SendRedirect()メソッドに比べて高速です。ただし、必要な日付やコンテンツを検索しているサーバーがブラウザに近づくことはなく、URLタブでURLを変更するようブラウザに要求することもありません。そのため、ユーザーにほとんど不便をかけません。


1

技術的にリダイレクトは、制御を別のドメインに移す必要がある場合、またはタスクを分離する必要がある場合に使用する必要があります。

たとえば、支払いアプリケーションでは、最初にPaymentProcessを実行してから、displayPaymentInfoにリダイレクトします。クライアントがブラウザを更新すると、displayPaymentInfoのみが再度実行され、PaymentProcessは繰り返されません。ただし、このシナリオでforwardを使用すると、PaymentProcessとdisplayPaymentInfoの両方が順次再実行されるため、データが矛盾する可能性があります。

他のシナリオでは、forwardはsendRedirectよりも高速であるため、効率的に使用できます。


0

リクエストディスパッチャは、リクエストまたはレスポンスをウェブリソースから別のウェブリソースにディスパッチするために使用されるインターフェースです。主に2つのメソッドが含まれています。

  1. request.forward(req,res):このメソッドは、あるWebリソースから別のリソースにリクエストを転送するために使用されます。つまり、あるサーブレットから別のサーブレットへ、または1つのWebアプリケーションから別のWebアプリケーションへ。

  2. response.include(req,res):このメソッドは、あるサーブレットから別のサーブレットへの応答を含めて使用されます

注:Request Dispatcherを使用することで、同じサーバーにリクエストまたはレスポンスを転送または含めることができます。

request.sendRedirect():これを使用することにより、さまざまなサーバー間で要求または応答を転送または含めることができます。この場合、クライアントはページのリダイレクト中にインティメイションを取得しますが、上記のプロセスではクライアントはインティメーションを取得しません。


-1

単に差とForward(ServletRequest request, ServletResponse response)してsendRedirect(String url)います

forward():

  1. forward()方法は、サーバ側で実行されます。
  2. リクエストは、同じサーバー内の他のリソースへの転送です。
  3. forward ()メソッドはサーブレットコンテナによって提供されるため、クライアントの要求プロトコルには依存しません。
  4. リクエストはターゲットリソースによって共有されます。
  5. このメソッドでは、1つの呼び出しのみが消費されます。
  6. サーバー内で使用できます。
  7. 転送されたメッセージは表示されません。透過的です。
  8. forward()この方法は、より速くあるsendRedirect()方法。
  9. RequestDispatcherインターフェースで宣言されています。

sendRedirect():

  1. sendRedirect()メソッドはクライアント側で実行されます。
  2. 要求は、別のサーバーへの他のリソースへの転送です。
  3. sendRedirect()メソッドはHTTPの下で提供されるため、HTTPクライアントでのみ使用できます。
  4. 宛先リソースに対して新しいリクエストが作成されます。
  5. 2つの要求と応答の呼び出しが消費されます。
  6. サーバーの内外で使用できます。
  7. リダイレクトされたアドレスを確認できますが、透過的ではありません。
  8. 新しいリクエストが作成されると、古いリクエストオブジェクトが失われるため、sendRedirect()メソッドは遅くなります。
  9. HttpServletResponseで宣言されています。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.