コントローラとルーティング
Webアプリケーションでは、 ブラウザからのリクエストをどの処理に結びつけるか が最も基本的な仕組みである。 この章では、Spring MVCの「コントローラ」と「ルーティング」について学ぶ。 URLの指定に応じてJavaの処理を呼び出し、結果としてHTMLを返すまでの一連の流れを理解する。
学習のゴール
- ルーティングの役割を理解し、URLと処理を結びつけられる
- GETとPOSTの違いを説明できる
@Controllerアノテーションの役割を説明し、コントローラクラスを作成できる@GetMapping/@PostMappingを使い、特定のURLに対応するメソッドを定義できる@GetMappingと@PostMappingの使い分けができる@RequestMappingの使い方がわかる- メソッドから
returnでビュー名を返せる - URLからどのメソッドが実行されるか判断できる
- コントローラが検出されない原因を推測できる
- ビューファイルの配置場所のルールを理解し、正しい構成で実装できる
- リダイレクトの仕組みを理解し、
redirect:プレフィックスを使って実装できる
ルーティングとは
ルーティングとは、 ブラウザから送られてきたURLから「どの処理を呼び出すか」を読み取る仕組み である。
例:http://localhost:8080/welcome
http://localhost:8080/welcome| | || | └─ パス(アプリ側で処理を振り分ける対象)| └─ ポート番号└─ ホスト名
この場合、ルーティングで指定する文字列は /welcome にあたる。
Spring MVCでは、この「パス」とプログラム(処理)を結びつけるために コントローラ を利用する。
URLのパスに加えて、ブラウザは HTTPメソッド と呼ばれる「リクエストの種類」も送信する。
| HTTPメソッド | 主な用途 | 例 |
|---|---|---|
| GET | データの取得・ページの表示 | URLを直接開く、リンクをクリックする |
| POST | データの送信・登録・更新 | フォームの送信ボタンを押す |
Spring MVCでは、同じURLでもGETとPOSTを別のメソッドで処理できる。
これが @GetMapping と @PostMapping の使い分けの根拠である。
コントローラの基本
Spring MVCにおける「コントローラ」とは、 ルーティングで読み取ったURLパスに対応する処理を実行し、結果としてビューを返す役割 を持つクラスである。
@Controllerアノテーションを付けたクラスは、リクエストを処理する役割を持つ- クラス自体は自分で
newしない。Springが自動的にインスタンス化して管理する(詳細はDIの章で解説) - Spring Bootでは、
@SpringBootApplicationが置かれているパッケージ またはそのサブパッケージ にコントローラを置く必要がある
com.example.demo ← ここに@SpringBootApplicationが置かれている├ DemoApplication.java└ controller/ ← コントローラはこのサブパッケージに置く└ HelloController.java
コントローラを正しく実装しても、 置くパッケージが間違っている と Springが検出できずリクエストは 404 になる。
よくある原因:
com.example.demoの下ではなく、全く別のパッケージ(例:com.controller)に置いてしまっているDemoApplication.javaと同じパッケージか、そのサブパッケージになっているか確認する
高度な設定で @ComponentScan を使えばスキャン範囲を変更できるが、今回は扱わない。
@GetMapping と @PostMapping
リクエストを処理するメソッドを決めるために、Spring MVCではアノテーションを使う。
@GetMapping — GETリクエストを処理する
ブラウザでURLを直接開いたとき(GETリクエスト)の処理を定義する。
@Controllerpublic class SampleController {@GetMapping("/welcome")public String welcome() {return "greet"; // → templates/greet.html を返す}}
@GetMapping("/welcome")…/welcomeへのGETリクエストをこのメソッドで処理するreturn "greet"…templates/greet.htmlを表示する(ビューの解決)
@PostMapping — POSTリクエストを処理する
フォームの送信ボタンを押したとき(POSTリクエスト)の処理を定義する。
@Controllerpublic class SampleController {@GetMapping("/contact")public String contactForm() {return "contact"; // フォームページを表示}@PostMapping("/contact")public String contactSubmit() {// フォームデータを処理するreturn "redirect:/thanks"; // 処理後にリダイレクト}}
同じURL /contact でも、GETとPOSTで異なるメソッドが呼び出される点に注目する。
@GetMapping と @PostMapping は、より汎用的な @RequestMapping の省略形である。
// @RequestMapping を使った書き方(冗長)
@RequestMapping(value = "/welcome", method = RequestMethod.GET)
public String welcome() { ... }
// @GetMapping を使った書き方(推奨)
@GetMapping("/welcome")
public String welcome() { ... }
| アノテーション | 対応するHTTPメソッド | 使い分け |
|---|---|---|
@RequestMapping | すべて(GET / POST / PUT / DELETE など) | 複数メソッドを1つで処理したい場合 |
@GetMapping | GET のみ | ページ表示・データ取得に使う(推奨) |
@PostMapping | POST のみ | フォーム送信・データ登録に使う(推奨) |
実務では @GetMapping / @PostMapping を使う方が意図が明確になるため推奨される。
ビューの置き場所
Spring Bootでは、ビューとして返すHTMLファイルは 必ず 以下の場所に配置する。
src/└ main/├ java/ … Javaコード└ resources/└ templates/ … Thymeleaf の HTMLファイル├ greet.html└ other.html
コントローラから return "greet"; と書くと、
Springは src/main/resources/templates/greet.html を探す。
templates 以下にディレクトリを作ることも可能である。
その場合、コントローラからはスラッシュ区切りで指定する。
@Controllerpublic class UserController {@GetMapping("/user")public String userDetail() {return "user/detail"; // → templates/user/detail.html を返す}}
return "greet" に対して templates/greet.html が存在しない場合、
TemplateInputException: Error resolving template [greet] というエラーが発生する。
チェックポイント:
- ファイルが
src/main/resources/templates/配下に置かれているか returnの文字列とファイル名(拡張子なし)が一致しているか- ディレクトリ構成を使う場合、
return "user/detail"のように正確に指定しているか
リダイレクト
コントローラのメソッドから 別のURLへリダイレクト させることができる。 フォーム送信後に別ページへ移動させる場合などに使う。
return の値を "redirect:/パス" の形式にするだけでよい。
@Controllerpublic class SampleController {@PostMapping("/register")public String register() {// 登録処理...return "redirect:/complete"; // /complete へリダイレクト}}
redirect:/complete… ブラウザに/completeへの再リクエストを促す- リダイレクト後は新しいGETリクエストとして処理されるため、フォームの二重送信を防げる
POST送信の後 は、原則としてリダイレクトを使う( PRGパターン )。
理由:ページをリロードすると同じPOSTリクエストが再送信されてしまうため、 リダイレクトによって最後のリクエストをGETに変えることで二重送信を防ぐ。
- フォーム送信 → 登録処理 →
redirect:/complete(推奨) - フォーム送信 → 登録処理 →
return "complete"→ リロード時に再送信される(非推奨)
よくある質問
Q. @GetMapping と @RequestMapping はどちらを使えばよいですか?
A. 基本的には @GetMapping / @PostMapping を使う方が推奨される。
メソッド名にHTTPメソッドの種類が含まれるため、コードを読んだときに意図がわかりやすくなる。
@RequestMapping は複数のHTTPメソッドを1つで扱いたい特別な場合に使う。
Q. コントローラのメソッド名は決まっていますか?(例:welcome でないとダメ?)
A. メソッド名は任意である。
welcome でも showTop でも displayPage でも動作する。
URLとの対応はアノテーション(@GetMapping のパス)で決まるため、メソッド名は自由につけてよい。
ただし、処理内容を表す意味のある名前をつけることが望ましい。
Q. コントローラを作ったのに 404 になります。なぜですか?
A. 主な原因は以下の3つである:
- パッケージの配置が間違っている —
@SpringBootApplicationのパッケージまたはそのサブパッケージに置く必要がある @Controllerアノテーションを忘れている — アノテーションがないとSpringに認識されない@GetMapping/@PostMappingのパス指定が間違っている — アクセスしているURLとパスが一致しているか確認する
Q. ビューファイルが見つからないエラー(TemplateInputException)の対処法は?
A. 以下を順番に確認する:
src/main/resources/templates/配下にHTMLファイルが存在するかreturnで指定した文字列とHTMLファイル名(.htmlを除いた部分)が一致しているか- サブディレクトリを使う場合、
return "user/detail"のようにスラッシュ区切りで指定しているか
本章のまとめ
- ルーティングとは、URLのパス部分と処理を結びつける仕組みである
- GETはページ表示・データ取得、POSTはフォーム送信・データ登録に使う
@Controllerを付けたクラスはSpringにより自動でインスタンス化される(自分でnewはしない)- コントローラは
@SpringBootApplicationのパッケージまたはそのサブパッケージに置く必要がある @GetMapping/@PostMappingでURLと処理を紐づける(@RequestMappingの省略形)- ビューは
src/main/resources/templates/配下に配置し、returnの文字列(拡張子なし)で指定する return "redirect:/パス"でリダイレクトができ、POST後のリダイレクトはフォーム二重送信を防ぐ
次章では、ブラウザから送られてくるリクエストパラメータをコントローラで受け取る方法を学ぶ。