forward()
との概念的な違いは何sendRedirect()
ですか?
9 に答える
Location
Web開発の世界では、「リダイレクト」という用語は、クライアントが新しい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を直接アクセスから隠したい場合に非常に役立ちます。/WEB-INF
JSPをフォルダに入れ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 --forward()メソッド
このメソッドを使用する
forward
と、リクエストは同じサーバー内の別のリソースに転送され、さらに処理されます。の場合
forward
、Webコンテナはすべての処理を内部で処理し、クライアントやブラウザは関与しません。
forward
オブジェクトでが呼び出されると、requestDispatcher
リクエストオブジェクトとレスポンスオブジェクトが渡されるため、リクエストを処理する新しいリソースに古いリクエストオブジェクトが存在します。視覚的には、転送されたアドレスを確認できません。透過的です。
この
forward()
メソッドの使用は。よりも高速ですsendRedirect
。forwardを使用してリダイレクトし、新しいリソースで同じデータを使用する場合
request.setAttribute()
は、リクエストオブジェクトを使用できるので使用できます。SendRedirect
の場合
sendRedirect
、リクエストは別のリソース、別のドメイン、または別のサーバーに転送され、さらに処理されます。を使用する
sendRedirect
と、コンテナはリクエストをクライアントまたはブラウザに転送するため、メソッド内で指定されたURLsendRedirect
は、クライアントへの新しいリクエストとして表示されます。呼び出しの場合
sendRedirect
、ブラウザによって新しい要求として扱われるため、古い要求オブジェクトと応答オブジェクトは失われます。アドレスバーに、リダイレクトされた新しいアドレスが表示されます。透明ではありません。
sendRedirect
完全に新しいリクエストが作成され、古いリクエストオブジェクトが失われるため、1回の追加のラウンドトリップが必要になるため、速度が低下します。2つのブラウザリクエストが必要です。ただし、
sendRedirect
では、新しいリソースに同じデータを使用する場合は、データをセッションに保存するか、URLとともに渡す必要があります。どちらがいいですか?
それは、どちらの方法がより有用であるかというシナリオに依存します。
制御を新しいサーバーまたはコンテキストに転送する必要があり、それが完全に新しいタスクとして扱われる場合は、に進み
sendRedirect
ます。一般に、ブラウザがWebページをリロードしたときに操作を安全に繰り返すことができ、結果に影響を与えない場合は、転送を使用する必要があります。
このRequestDispatcher
インターフェースでは、サーバー側の転送/インクルードを実行できますsendRedirect()
が、クライアント側のリダイレクトは実行できます。クライアント側のリダイレクトでは、サーバーは(一時的なリダイレクト)のHTTPステータスコードを送り返します。これにより、Webブラウザーは、リダイレクトされた場所にあるコンテンツに対して302
まったく新しいHTTP要求を発行します。GET
対照的に、RequestDispatcher
インターフェースを使用する場合、新しいリソースへのインクルード/転送は完全にサーバー側で処理されます。
やりたいことに応じて、これらの方法のいずれかが「より良い」、つまりより適切な場合があります。
ブラウザにラウンドトリップせずに別のページからデータを取得する限り、サーバー側のリダイレクトは高速です。ただし、ブラウザに表示されるURLは元のアドレスのままであるため、そこに少し矛盾が生じています。
クライアント側のリダイレクトは、完全に異なるサーバーに送信したり、プロトコルを変更したり(HTTPからHTTPSに変更したり)、またはその両方を行うことができる限り、より用途が広くなります。そして、ブラウザは新しいURLを認識しています。ただし、サーバーとクライアントの間で余分なやりとりが必要です。
SendRedirect()
サーバー間でコンテンツを検索します。コンテンツのURLを送信してブラウザを親密にする必要があるため、低速です。次に、ブラウザは同じサーバー内または別のサーバー内のコンテンツに対する新しいリクエストを作成します。
RquestDispatcher
サーバー内のコンテンツを検索するためのものだと思います。そのサーバー側のプロセスであり、SendRedirect()
メソッドと比較して高速です。ただし、必要な日付やコンテンツを検索しているサーバーをブラウザに通知することはなく、[URL]タブでURLを変更するようにブラウザに要求することもありません。そのため、ユーザーにほとんど不便をかけません。
制御を別のドメインに移す必要がある場合、またはタスクの分離を実現する必要がある場合は、技術的にリダイレクトを使用する必要があります。
たとえば、支払いアプリケーションでは、最初にPaymentProcessを実行してから、displayPaymentInfoにリダイレクトします。クライアントがブラウザを更新すると、displayPaymentInfoのみが再度実行され、PaymentProcessは繰り返されません。ただし、このシナリオでフォワードを使用すると、PaymentProcessとdisplayPaymentInfoの両方が順番に再実行されるため、データが不整合になる可能性があります。
他のシナリオでは、sendRedirectよりも高速であるため、forwardを使用すると効率的です。
Request Dispatcherは、Webリソースから別のWebリソースに要求または応答をディスパッチするために使用されるインターフェースです。主に2つの方法が含まれています。
request.forward(req,res)
:このメソッドは、あるWebリソースから別のリソースにリクエストを転送するために使用されます。つまり、あるサーブレットから別のサーブレットへ、またはあるWebアプリケーションから別のWebアプリケーションへ。response.include(req,res)
:このメソッドは、あるサーブレットから別のサーブレットへの応答を含めて使用されます
注:Request Dispatcherを使用することで、同じサーバーにリクエストまたはレスポンスを転送または含めることができます。
request.sendRedirect()
:これを使用することで、異なるサーバー間でリクエストまたはレスポンスを転送または含めることができます。これでは、クライアントはページのリダイレクト中に情報を取得しますが、上記のプロセスではクライアントは情報を取得しません
Forward(ServletRequest request, ServletResponse response)
との違いsendRedirect(String url)
は
前方():
forward()
メソッドはサーバー側で実行されます。- リクエストは、同じサーバー内の他のリソースに転送されます。
forward ()
メソッドはサーブレットコンテナによって提供されるため、クライアントの要求プロトコルに依存しません。- リクエストはターゲットリソースによって共有されます。
- このメソッドで使用される呼び出しは1つだけです。
- サーバー内で使用できます。
- 転送されたメッセージは表示されません。透過的です。
- この
forward()
方法は方法よりも高速ですsendRedirect()
。 - インターフェイスで宣言され
RequestDispatcher
ます。
sendRedirect():
- sendRedirect()メソッドはクライアント側で実行されます。
- リクエストは、別のサーバーの他のリソースに転送されます。
- sendRedirect()メソッドはHTTPで提供されるため、HTTPクライアントでのみ使用できます。
- 宛先リソースに対して新しい要求が作成されます。
- 2つの要求と応答の呼び出しが消費されます。
- サーバーの内外で使用できます。
- リダイレクトされたアドレスを確認できますが、透過的ではありません。
- 新しいリクエストが作成されると古いリクエストオブジェクトが失われるため、sendRedirect()メソッドは遅くなります。
- HttpServletResponseで宣言されています。