Spring MVCのフォワードとリダイレクトの違いと使い分け完全解説!初心者向け
生徒
「Spring MVCでredirect:/とかforward:/って書いてあるのを見たんですが、これってどう違うんですか?」
先生
「それはSpring MVCでリクエストを他のページに移すときの指定方法ですね。フォワードとリダイレクトは仕組みが違うので、用途によって使い分ける必要がありますよ。」
生徒
「どっちを使えばいいか迷ってしまって…具体的な違いを知りたいです!」
先生
「それでは、forward:/とredirect:/の基本的な違いと、使いどころ、注意点などを丁寧に説明していきましょう。」
1. Spring MVCのフォワードとリダイレクトの基本
「1. Spring MVCのフォワードとリダイレクトの基本」の重要ポイントを、初心者の方にも分かりやすく簡潔に解説します。
Spring MVCを利用したWeb開発において、コントローラーから「どの画面を表示するか」を制御する仕組みは非常に重要です。通常、return "home";のようにテンプレート名を返すと、そのままHTMLが表示されます。しかし、特定の処理後に別のプログラムへ処理を委ねたい場合には、forward:/やredirect:/という接頭辞を使用します。
これらは一見似ていますが、「サーバーの中でこっそり中身を入れ替える(フォワード)」のか、「ブラウザに別のURLへ行くよう命令を出す(リダイレクト)」のかという決定的な違いがあります。プログラミング未経験の方でもイメージしやすいよう、役所の窓口に例えたサンプルで考えてみましょう。
- フォワード(Forward):窓口Aの担当者が、後ろにいる担当者Bに書類を回して処理を継続する。相談者は窓口Aの前に座ったままで、誰が処理したかは意識しない。
- リダイレクト(Redirect):窓口Aの担当者が「その件は2階の5番窓口へ行ってください」と指示する。相談者は一度席を立ち、自分の足で新しい窓口へ移動する。
@Controller
public class SampleController {
// フォワードの例:URLは /entry のまま、中身だけ /confirm に移る
@GetMapping("/entry")
public String entry() {
return "forward:/confirm";
}
// リダイレクトの例:ブラウザに /success へ移動するように命令を出す
@PostMapping("/submit")
public String submit() {
return "redirect:/success";
}
}
このように、Spring MVCでは戻り値の文字列を工夫するだけで、通信の挙動をコントロールできます。それぞれの仕組みを詳しく見ていきましょう。
forward:/〜
サーバー内部で別の処理に渡すため、ユーザーのブラウザに表示されているURLは変わりません。リクエスト(お願い事)の内容をそのまま次の処理に引き継げます。
redirect:/〜
ブラウザに対して「新しいURLにアクセスし直して!」と指示を出します。URLが新しいものに書き換わり、全く新しいリクエストとして処理が始まります。
2. forward:/ の使い方と特徴
forward:/(フォワード)は、サーバーの内部で別のプログラムに「バトンタッチ」をする仕組みです。最大の特徴は、ユーザーが使っているブラウザに「移動したこと」を知らせない点にあります。
あなたがデパートの「総合案内所」で「落とし物の相談」をしたとします。案内所のスタッフが、自分では答えられないので、後ろの席にいる「遺失物担当者」に書類を回して、そのまま回答をもらうのがフォワードです。
あなたは窓口を動いていませんし、誰が最終的に回答を用意したのかは分かりません。これと同じで、ブラウザのURLも元のまま変わらないのです。
フォワードを使うと、最初のリクエスト(お願い事)に含まれるデータ(入力内容など)を、次の処理へそのまま引き渡すことができます。これを「リクエストスコープの維持」と呼びます。Javaのコードで具体的な流れを見てみましょう。
@Controller
public class ForwardController {
// 1. ユーザーが最初にアクセスするURL
@GetMapping("/start")
public String start(HttpServletRequest request) {
// サーバー内のメモ帳(リクエスト)に名前を書き込む
request.setAttribute("userName", "たろうさん");
// URLは /start のまま、内部で /next という処理にバトンタッチ
return "forward:/next";
}
// 2. バトンを受け取った後の処理
@GetMapping("/next")
public String next() {
// 最終的に表示するHTMLファイル(result.html)を指定
return "result";
}
}
実行結果のポイント
- ブラウザのアドレス欄は
/startのまま動きません。 - 内部的には
/nextの処理が動いており、画面にはresult.htmlの内容が表示されます。 /startでセットした「たろうさん」というデータは、/nextでも消えずに使うことができます。
このように、一つの作業を複数のプログラムで分割して行いたいけれど、ユーザーにはその裏側を見せたくない(URLを変えたくない)場合に、フォワードは非常に便利な方法です。
3. redirect:/ の使い方と特徴
redirect:/は、ブラウザに「このURLへ移動してください」と指示を出す方法です。リダイレクト後は新しいリクエストになるため、リクエストスコープのデータは引き継がれません。
@PostMapping("/form")
public String handleForm(RedirectAttributes redirectAttributes) {
redirectAttributes.addFlashAttribute("message", "登録しました!");
return "redirect:/complete";
}
@GetMapping("/complete")
public String complete() {
return "complete"; // complete.html を表示
}
このようにリダイレクト後はURLが/completeに変わり、表示も切り替わります。リダイレクト属性(Flash Attribute)を使えば、一時的なデータを渡すことが可能です。
4. フォワードとリダイレクトの違いを一覧比較
「4. フォワードとリダイレクトの違いを一覧比較」の重要ポイントを、初心者の方にも分かりやすく簡潔に解説します。
| 項目 | forward:/ | redirect:/ |
|---|---|---|
| 処理の流れ | サーバー内部での転送 | ブラウザが別リクエストを送る |
| URL | 変わらない | 変わる |
| リクエスト情報 | そのまま引き継ぐ | 失われる(Flash使えば可) |
| 用途 | 同一処理内でのページ遷移 | 完了画面や一覧画面への遷移 |
5. forward:/ と redirect:/ の実行結果の違い
それぞれの動作を確認してみましょう。
forwardの結果
URLが変わらず、内部で次の処理に移るため、フォームなどの再送信が起こることがあります。
URL: /start
表示ページ: result.html
redirectの結果
リダイレクト後のURLが表示され、再読み込みしても同じページが出るようになります。
URL: /complete
表示ページ: complete.html
6. 使い分けのベストプラクティス
実務では以下のように使い分けるとよいでしょう。
- forward → バリデーションエラーがあったときの入力画面再表示
- redirect → 登録完了後のサンクスページ、一覧画面遷移
- Post/Redirect/Getパターン → フォーム送信後のリロードで二重登録を防ぐ
7. リダイレクト属性(RedirectAttributes)の活用法
「7. リダイレクト属性(RedirectAttributes)の活用法」の重要ポイントを、初心者の方にも分かりやすく簡潔に解説します。
リダイレクトでデータを渡すにはRedirectAttributesを使います。これにより、一時的なメッセージ(Flash Attribute)を渡すことができます。
@PostMapping("/submit")
public String submitForm(RedirectAttributes attr) {
attr.addFlashAttribute("notice", "送信成功!");
return "redirect:/thanks";
}
@GetMapping("/thanks")
public String thanks() {
return "thanks"; // thanks.html に notice を表示
}
テンプレートでは以下のようにしてnoticeを表示できます。
<div th:if="${notice}" class="alert alert-success">
<p th:text="${notice}"></p>
</div>
まとめ
Spring MVCのフォワードとリダイレクトの仕組みを理解することで、画面遷移の流れやリクエストスコープの動作、適切な使い分けがより明確になります。とくに業務システム開発では、入力画面から確認画面、完了画面へと進む一連の流れの中で、どの遷移方法を選ぶかがユーザー体験にも大きく影響します。フォワードはサーバー内部で静かに処理が移り、リクエストスコープの属性をそのまま保持するため、入力値の再表示やバリデーションエラー時に自然に利用できます。一方でリダイレクトはブラウザに明示的な移動を指示するため、完了画面の表示や再読み込み時の二重送信回避など、ユーザー操作に対する安全性を高める動作が求められる場面で役立ちます。 また、POST後のリダイレクトを用いる「PRGパターン」は現場では非常によく使われる設計であり、データ登録後の二重送信を避けるための基本的な考え方として知っておく必要があります。リダイレクトでは通常リクエストスコープが引き継がれないものの、Flash Attributeを使うことで一時的なメッセージを安全に渡すことが可能であり、ユーザー通知や確認メッセージの表示に広く活用されます。 ここであらためて、フォワードとリダイレクトの動作を確認する簡単なサンプルプログラムを示し、動作の違いをさらに深く理解していきましょう。実際の画面遷移を想定したコード例を見ることで、URLの変化やリクエストスコープの扱いがどのように変わるかを具体的に体感でき、Spring MVCの遷移設計に自信を持って取り組めるようになります。
フォワードとリダイレクトのサンプルコード
@GetMapping("/input")
public String input(HttpServletRequest request) {
request.setAttribute("error", "未入力の項目があります");
return "forward:/form";
}
@PostMapping("/register")
public String register(RedirectAttributes redirectAttributes) {
redirectAttributes.addFlashAttribute("success", "登録が完了しました");
return "redirect:/finish";
}
@GetMapping("/finish")
public String finish() {
return "finish"; // finish.html を表示
}
このように、フォワードは内部処理で値を引き継いで画面へ遷移し、リダイレクトはユーザーのブラウザを通して新しいURLへ移動します。URLの変化や入力再表示の可否など、動作の違いを理解したうえで適切に利用することで、安定したアプリケーションの構築が可能になります。とくに業務システムでは再読み込みによる二重送信がトラブルにつながりやすいため、リダイレクトとFlash Attributeの組み合わせは非常に重要です。
生徒
「フォワードとリダイレクトの違いがようやくつかめてきました。URLが変わるかどうかや、リクエストスコープの扱いがとても重要なんですね。」
先生
「そのとおりです。特にフォーム処理では、フォワードで入力値を再表示したり、リダイレクトで二重送信を防止したりと、それぞれの特性を理解して使い分けることが大切ですよ。」
生徒
「Flash Attributeがリダイレクトでも一時的なメッセージを渡せるという仕組みも便利ですね。実務でよく使われる理由が分かりました。」
先生
「はい。通知メッセージや成功メッセージなどはリダイレクト後の画面で表示されることが多いので、とても重宝される機能なんです。今日学んだ内容をしっかり身につけて、今後のSpring MVC開発でも自信を持って使いこなしてくださいね。」
生徒
「ありがとうございました!実際にプロジェクトで活用してみます!」