1. GETリクエスト と POSTリクエスト の違い
HTTPリクエスト方式(HTTPメソッド)にはいくつか種類がありますが、Web開発で最も頻繁に使われるのが GET と POST です 。
① GETリクエスト(データの取得・閲覧)
主な役割: サーバーからデータを取得(照会・閲覧)する際に使用します。例えば「ユーザー一覧画面の表示」や「記事の検索」などがこれに該当します。
データの保持方法: 送信したいデータ(パラメータ)をURLの末尾(クエリパラメータ)に含めて送信します。
特徴: URLにデータが直接露出するため、ブックマーク(お気に入り登録)ができるというメリットがあります。ただし、パスワードや個人情報などの機密データを送るのには向いていません。
② POSTリクエスト(データの登録・保存)
主な役割: サーバーへデータを送信して登録・保存(変更・削除)する際に使用します。例えば「新規会員登録」「記事の投稿」「商品の決済」などがこれに該当します。
データの保持方法: 送信データをURLではなく、Request Body(リクエストボディ)という見えない領域に含めて送信します。
特徴: URLにデータが出ないため、GETに比べて安全性が高く、大量のデータや画像などのファイルも送信することができます。
💡 Controllerでのアノテーション使い分け
// ユーザー一覧画面などの「データ取得」はGetMapping
@GetMapping("/member/list")
public String list() {
return "member/list";
}
// 会員登録などの「データ保存」はPostMapping
@PostMapping("/member/save")
public String save() {
return "home";
}
2. HTML Form タグによるデータ送信
フロントエンド(HTML)からサーバー(Controller)へPOST方式でデータを送る際は、
タグを使用します 。<form action="/member/save" method="post">
<label>名前</label>
<input type="text" name="name">
<label>年齢</label>
<input type="number" name="age">
<button type="submit">登録</button>
</form>
3. フォームデータの受け取り方(引数の処理方法)Controller側で、画面から送られてきた「名前(name)」と「年齢(age)」を受け取るには、主に2つの方法があります。
① @RequestParam を使って個別に受け取る
@PostMapping("/member/save")
public String save(@RequestParam String name, @RequestParam Integer age) {
System.out.println("名前: " + name);
System.out.println("年齢: " + age);
return "home";
}
特徴: シンプルですが、受け取る項目(フィールド)が増えるほどメソッドの引数が長くなり、管理が大変になります 。
② DTO(オブジェクト)を使って一括で受け取る【実務推奨】
実務では、リクエストデータを一つのオブジェクト(DTO)にまとめて管理するのが一般的です 。ここで大活躍するのが Lombok(ロンボク) というライブラリです 。
📦 DTO(Memberクラス)の作成
Lombokの @Data アノテーションを付与するだけで、Getter/Setter、ToString、EqualsAndHashCode、RequiredArgsConstructor などの定型コード(ボイラープレートコード)をコンパイル時に自動生成してくれます 。
import lombok.Data;
@Data
public class Member {
private String name;
private Integer age;
}
🛠️ Controller側での受け取り(データバインディング)
Controllerの引数に作成した Member オブジェクトを指定するだけで、Springが自動的に データバインディング(Data Binding) を行ってくれます 。
@PostMapping("/member/save")
public String save(Member member) {
// 内部的に自動で new Member() され、setName() や setAge() が実行される
System.out.println(member.getName());
System.out.println(member.getAge());
return "home";
}
4. なぜリダイレクト(Redirect)が必要なのか?
会員登録や記事の作成が完了した後、そのまま結果画面(HTML)を返してしまうと、重大な問題が発生することがあります 。
// ❌ リダイレクトを使わない良くない例
@PostMapping("/member/save")
public String save(Member member) {
memberService.save(member);
return "member/list"; // 画面(View)の書き換えのみ
}
⚠️ リダイレクトをしないとどうなる?(重複リクエストの問題)上記のコードの状態でユーザーがブラウザの「画面更新(F5キーなど)」を押すと、直前に行った POSTリクエスト(データの保存)がもう一度サーバーに送信されてしまいます 。その結果、同じユーザーが二重に登録されたり、決済が2回行われたりするエラー(バグ)に繋がります 。
⭕ 解決策:PRG(Post-Redirect-Get)パターンこの問題を防ぐために、POST処理が終わったら必ず redirect: を使ってブラウザに「別のURLへ再リクエストして!」と指示を出します 。
// リダイレクトを活用した実務の標準例
@PostMapping("/member/save")
public String save(Member member) {
memberService.save(member);
// 処理完了後、指定したURL(GETメソッド)へブラウザを強制移動させる
return "redirect:/member/list";
}
リダイレクトの動作フロー
- ブラウザが POST /member/save でデータを送信 。
- サーバーがデータを保存し、redirect:/member/list を返却 。
- ブラウザが自動的に GET /member/list という新しいリクエストをサーバーに再送 。
- これにより、ユーザーが画面を更新しても「GETリクエスト(一覧の再読込)」が走るだけなので、データの重複登録を防ぐことができます 。
まとめ
GET : データの取得・照会に使用 。URLにデータが載る 。
POST : データの登録・保存に使用 。Request Bodyにデータが入る 。
Data Binding : 画面からの送信データを、Springが自動でJavaオブジェクトに格納してくれる仕組み 。
Redirect : 画面の移動ではなく、URLの再リクエストをブラウザに命じる機能(二重送信の防止) 。