こんにちは、かつコーチです。
前回、@Controllerと@RestControllerの違いを整理しました。
今回は、Controllerが実際にどうやって「どのURLへのどんなリクエストか」を判別しているのかを見ていきます。@GetMappingと@PostMappingは、URLの取得(GET)とデータ送信(POST)を振り分けるための基本アノテーションです。
この2つの使い分けを理解すると、フォーム送信を伴うWebアプリの作り方がぐっと見えやすくなります。
@GetMapping・@PostMappingとは?
HTTPメソッドとルーティングの関係
HTTPメソッドとは、ブラウザやクライアントがサーバーに対して「何をしたいか」を伝えるための種類です。
代表的なものに、データを取得するGETと、データを送信・登録するPOSTがあります。
Spring MVCでは、この2種類のHTTPメソッドを@GetMappingと@PostMappingというアノテーションでURLに紐づけます。
@Controller
public class UserController {
@GetMapping("/users/new")
public String newUserForm() {
return "users/new"; // 入力フォームの画面を表示
}
@PostMapping("/users")
public String createUser(@RequestParam String name) {
// 送信されたデータを処理する
System.out.println("登録: " + name);
return "redirect:/users";
}
}
同じ/users系のURLでも、GETなら「フォームを表示」、POSTなら「データを登録」というように、目的に応じて処理を分けられるのがポイントです。
なぜ2つに分けて設計するのか
もし1つのメソッドでGETとPOSTの両方を受けてしまうと、メソッドの中で「今回はどちらのリクエストか」を毎回判定するコードが必要になり、読みにくくなります。@GetMappingと@PostMappingでメソッドごと分けておけば、「このメソッドは画面表示専用」「このメソッドは登録処理専用」と役割がひと目で分かり、保守性が高まります。
基本の書き方・実装手順
手順1:一覧取得はGETで受ける
まずは一覧画面のように、データを取得して表示するだけの処理を@GetMappingで作ります。
@Controller
@RequestMapping("/users")
public class UserController {
@GetMapping
public String list(Model model) {
model.addAttribute("message", "こんにちは、かつコーチです。");
return "users/list";
}
}
クラスに@RequestMapping("/users")を付けておくと、そのクラス内の全メソッドのURLに/usersという共通の接頭辞が付きます。
メソッド単位で毎回フルパスを書かなくて済むため、URLが増えてきたときに管理しやすくなります。
手順2:フォーム送信はPOSTで受け取る
続いて、フォームから送られたデータを受け取る処理を@PostMappingで作ります。
値を受け取るには@RequestParamを使います。
@PostMapping
public String create(@RequestParam String name, @RequestParam String email) {
// 本来はここでService層に処理を委譲する
System.out.println(name + " / " + email);
return "redirect:/users";
}
@RequestParamは、フォームのname属性と一致する値を自動的にメソッドの引数に渡してくれます。
処理が終わったらredirect:/usersのようにredirect:を付けて返すことで、一覧画面へリダイレクトし、フォームの再送信によるデータ二重登録を防げます。
つまずきやすい設定・注意点
Thymeleafなどでフォームを作る際は、<form>タグのmethod属性をpostにし、action属性を対象のURLに合わせる必要があります。
ここがずれていると、意図しないメソッドが呼ばれたり、405エラーになったりします。
<form th:action="@{/users}" method="post">
<input type="text" name="name" />
<input type="text" name="email" />
<button type="submit">登録</button>
</form>
よくあるつまずきポイント・エラー対処
GETで受けるべき処理をPOSTのままにしてしまう
初心者がよくやってしまうのが、フォーム表示用のURLまで@PostMappingにしてしまうケースです。
❌ Before
@PostMapping("/users/new")
public String newUserForm() {
return "users/new";
}
ブラウザでこのURLに直接アクセスすると、以下のようなエラーになります。
Whitelabel Error Page
This application has no explicit mapping for /error...
(実際にはブラウザから直接アクセスするとGETリクエストになるため、405 Method Not Allowedが発生する)
筆者も学習し始めの頃、フォーム表示用のURLをすべて@PostMappingで統一してしまい、ブラウザで直接開くたびに405エラーが出て原因が分からず時間を溶かした経験があります。
原因は単純で、ブラウザでURLを直接叩く操作は常にGETリクエストになるため、@PostMappingしか定義していないメソッドには到達できなかったのです。
✅ After
@GetMapping("/users/new")
public String newUserForm() {
return "users/new";
}
「画面を表示するだけ=GET」「データを変更する=POST」という原則を意識すると、この種のミスは防げます。
応用・一歩先の使い方
@GetMapping・@PostMappingのほかにも、更新用の@PutMapping、削除用の@DeleteMappingが用意されています。
REST APIを設計する際は、これらを組み合わせてCRUD(作成・取得・更新・削除)をHTTPメソッドの意味に沿って表現するのが一般的です。
画面遷移中心のThymeleafアプリではGET・POSTが中心になりますが、将来的にAPIを設計する際にはこの発展形も覚えておくと役立ちます。
まとめ
この記事のポイント
@GetMappingは「データ取得・画面表示」、@PostMappingは「データ送信・登録処理」に使う- クラスに
@RequestMappingを付けると、URLの共通接頭辞をまとめられる - フォームの
method属性とControllerのアノテーションを一致させないと405エラーになる - ブラウザで直接URLを開く操作は常にGETになる点に注意する
次に読むべき記事
リクエストの受け取り方が分かったら、次は「Thymeleafでビューを作成する基本」で、実際に画面を組み立てる方法を見ていきましょう。
タグ: Spring Boot, 初心者向け, フレームワーク基礎