複数のメソッドにマッピングする方法(GETとPOST)を完全解説!Spring Bootでコントローラーを正しく使おう
新人
「Spring Bootのコントローラーで、GETとPOSTを両方使うにはどうしたらいいんですか?」
先輩
「それは、メソッドに@GetMappingや@PostMappingを使って、URLごとに分けて記述するんだよ。同じURLでも、HTTPメソッドによって別の処理をさせることができるよ。」
新人
「GETとPOSTって何が違うんですか?どんなときに使い分けるんでしょうか?」
先輩
「いいところに気づいたね。まずはGETとPOSTの違いから整理していこう!」
1. GETとPOSTの基本的な違いとは?
Webアプリケーションでは、ユーザーがブラウザからアクセスしたときに、さまざまな情報をサーバーへ送信しています。その方法には「GETメソッド」と「POSTメソッド」という2つの代表的な方法があります。
GETメソッドは、主に「情報を取得する」ために使われます。例えば、Webページを表示する、検索結果を取得するなどが代表的です。URLにパラメータがつくため、ユーザーにも見える形式になります。
一方で、POSTメソッドは「データを送信する」ために使います。フォームに入力された内容をサーバーへ送る場合や、データベースに新しい情報を追加するときなどに使用されます。URLには値が表示されず、セキュリティ的にもGETより安全です。
この2つの違いは、Spring Bootのコントローラーを作成するときにも非常に重要です。GETはデータ取得、POSTはデータ登録と考えると分かりやすいでしょう。
2. Spring BootでGETとPOSTを使う場面とは?
Spring Bootの開発では、@Controllerクラスを作成して、リクエストを処理します。その際、URLに応じたメソッドを定義するために@GetMappingや@PostMappingといったアノテーションを使います。
たとえば、「お問い合わせフォーム」を例にすると分かりやすいです。
- 最初に入力画面を表示する:GET
- フォームの内容を送信して処理する:POST
このように、同じURLでもGETとPOSTで異なるメソッドにマッピングすることができます。Spring Bootでは、コントローラーに複数のメソッドを定義して、それぞれのHTTPメソッドに対応することが可能です。
以下は、その基本的な書き方です。
package com.example.demo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
@Controller
public class ContactController {
@GetMapping("/contact")
public String showForm(Model model) {
model.addAttribute("message", "お問い合わせフォームを表示します。");
return "contact-form";
}
@PostMapping("/contact")
public String submitForm(Model model) {
model.addAttribute("message", "お問い合わせ内容を送信しました。");
return "contact-result";
}
}
この例では、/contactというURLに対して、GETメソッドではフォームを表示し、POSTメソッドではその入力を処理しています。それぞれに対応するHTMLテンプレート(contact-form.htmlやcontact-result.html)を用意することで、実際の画面に内容を表示することができます。
こうした処理は、Spring Boot + Gradleで構成されたPleiadesのプロジェクトでもそのまま利用可能です。@RestControllerではなく@Controllerを使うことで、HTMLを返す画面表示型のアプリケーション開発が可能になります。
初心者の方は、まずこのようにGETとPOSTをURLごとに分けてマッピングし、入力と送信の流れを分ける形を覚えるとよいでしょう。
3. 同じURLに対してGETとPOSTを使い分ける方法
Spring Bootのコントローラーでは、同じURLに対してGETとPOSTの両方を使い分けることができます。この仕組みにより、ユーザーがアクセスするURLは同じでも、アクセスの種類に応じて異なる処理を実行できます。
具体的には、@GetMapping("/contact")でフォーム画面を表示し、@PostMapping("/contact")で送信されたデータを処理する構成です。どちらも/contactというURLですが、HTTPメソッドが異なるため、Spring Bootは自動的にどちらのメソッドを実行するかを判断してくれます。
この方法を使えば、画面遷移が自然になり、ユーザーにとっても分かりやすい設計になります。例えば、以下のような構成がよく使われます。
- GET:画面を表示する(初期表示)
- POST:送信されたデータを受け取り、結果画面を表示する
初心者が混乱しやすいポイントとして、「GETとPOSTで同じURLでもよいのか?」という疑問がありますが、Spring Bootではこれが基本的な使い方です。フレームワーク側で自動的にHTTPメソッドを判別して処理してくれるため、URLを分けなくても問題ありません。
4. Spring Bootでフォーム入力を処理するサンプルコード
ここでは、Spring Bootのコントローラーでフォーム入力をGETとPOSTの両方で処理するサンプルコードを紹介します。画面表示にはthymeleafを使いますが、テンプレートの詳細は今回は省略します。
まずはフォームを表示するGETメソッド、次にデータを受け取って処理するPOSTメソッドの2つを用意します。
package com.example.demo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
@Controller
public class ContactController {
@GetMapping("/contact")
public String showForm() {
return "contact-form";
}
@PostMapping("/contact")
public String submitForm(@RequestParam("name") String name,
@RequestParam("email") String email,
Model model) {
model.addAttribute("name", name);
model.addAttribute("email", email);
return "contact-result";
}
}
@RequestParamを使って、フォームで送信されたnameとemailの値を受け取り、Modelにセットしています。そしてcontact-result.htmlの画面に渡すことで、送信結果を表示します。
このような構成により、ユーザーは/contactにアクセスしてフォームを表示し、入力後に送信すると/contactのPOSTメソッドが呼び出され、結果画面が表示されます。
なお、フォーム側ではmethod="post"を明示的に指定する必要があります。これにより、送信時にPOSTメソッドが呼び出されます。
<form action="/contact" method="post">
<label for="name">お名前:</label>
<input type="text" id="name" name="name">
<br>
<label for="email">メールアドレス:</label>
<input type="email" id="email" name="email">
<br>
<button type="submit">送信</button>
</form>
このHTMLをcontact-form.htmlに記述しておけば、Spring Bootのコントローラーと連携してスムーズに動作します。
5. Modelを使って画面にデータを渡す基本的な流れ
Spring Bootの@Controllerでは、画面にデータを渡すためにModelを使います。Modelは、テンプレートに渡したいデータを保持するための仕組みです。
たとえば、ユーザーが送信した名前やメールアドレスを画面に表示したいとき、POSTメソッドの中でmodel.addAttribute("name", name)のように記述します。これにより、テンプレート側でnameという変数を使用できるようになります。
テンプレートファイル(HTML)では、以下のように書いてデータを表示します。
<p>お名前:<span th:text="${name}"></span></p>
<p>メールアドレス:<span th:text="${email}"></span></p>
このように、Modelを介してデータを渡すことで、HTMLテンプレートにJava側のデータを表示することが可能になります。これはSpring Bootで画面を表示する際に基本となる考え方です。
また、Modelにセットしたデータは、画面遷移時に一時的に保持され、次の表示画面で使用されます。そのため、入力→確認→完了といったフォーム処理の流れにも柔軟に対応できます。
初めてSpring Bootでフォームを扱う場合は、「Modelにデータをセット→HTMLで表示」の流れをしっかり理解しておくことが重要です。この考え方が身につけば、実践的なWebアプリケーション開発にも対応できるようになります。
6. GETとPOSTでよくあるミスとその対処法
Spring BootでGETとPOSTのメソッドを使い分ける際に、初心者の方がよく直面するミスについて解説します。これらのミスは、簡単に見落としてしまうものが多いため、あらかじめ知っておくことでトラブルを防ぐことができます。
よくあるミス①:HTMLのformタグにmethodを指定していない
フォームを作成するときに、method="post"を付け忘れると、ブラウザは自動的にGETで送信してしまいます。その結果、POSTメソッドの処理が呼び出されず、「404エラー」や「405エラー」が発生します。
対処法:フォームタグにmethod="post"を必ず指定しましょう。
よくあるミス②:@PostMappingの引数に@RequestParamを忘れている
POSTメソッドでデータを受け取るとき、@RequestParamを付けないと、値が取得できません。nullになったり、エラーになる原因になります。
対処法:引数には必ず@RequestParamを付けるようにしましょう。
よくあるミス③:Modelにデータを渡し忘れて画面に値が表示されない
データは受け取れていても、画面に表示するためにはModelにセットする必要があります。忘れると、テンプレートで変数が空のままになってしまいます。
対処法:model.addAttribute("キー名", 値)を忘れずに記述しましょう。
よくあるミス④:@Controllerを@RestControllerと書いてしまう
初心者が混同しやすいのが、@RestControllerとの使い分けです。画面を表示する場合には@Controllerが正解です。間違って@RestControllerにすると、HTMLではなく文字列がそのまま返ってしまいます。
対処法:画面を表示する処理では必ず@Controllerを使用してください。
7. メソッドの使い分けで気をつけるポイント(セキュリティ・リダイレクトなど)
GETとPOSTを正しく使い分けることで、安全で分かりやすいWebアプリケーションを作ることができます。ここでは、フォーム処理で注意しておきたいポイントを整理します。
① GETでは機密情報を送らない
GETメソッドは、URLにパラメータが表示されるため、個人情報やパスワードなどの機密情報を送信するのには適していません。たとえば、ログインフォームでIDやパスワードをGETで送ると、履歴やログに残ってしまい危険です。
対処法:ユーザーが入力した情報を送るときは、必ずPOSTメソッドを使いましょう。
② POSTのあとにリダイレクトを使うと再送信を防げる
フォームを送信したあと、ブラウザで「戻る」ボタンを押すと、POSTが再実行されてしまうことがあります。これを「二重送信」と呼びます。
対処法:POSTのあとにredirect:/thanksのようにリダイレクトを使うことで、再送信を防ぐことができます。
@PostMapping("/contact")
public String submitForm(@RequestParam("name") String name,
@RequestParam("email") String email,
RedirectAttributes redirectAttributes) {
redirectAttributes.addFlashAttribute("message", "送信が完了しました。");
return "redirect:/thanks";
}
③ URL設計をシンプルにする
GETとPOSTで同じURLを使っても問題ありませんが、処理内容によっては分けた方が見やすいこともあります。URLは人間にも分かりやすく、整理された構成にすることが大切です。
④ CSRF対策を忘れない
Spring Bootでは、フォーム送信時に自動でCSRFトークンが含まれますが、テンプレート側でも<input type="hidden" name="_csrf">が必要になる場合があります。
Thymeleafを使っている場合は、th:actionやth:methodを使えば自動で設定されるため、特別な対応は不要です。
8. よくある質問とその回答(FAQ形式)
Q:GETとPOSTで同じURLにしても大丈夫ですか?
はい、大丈夫です。Spring Bootでは、HTTPメソッドによって処理を自動で切り分けてくれるため、同じURLでも問題ありません。
Q:@RestControllerと@Controllerの違いは何ですか?
@RestControllerは、HTMLではなく文字やJSONなどを返す用途で使います。一方、画面表示をする場合は@Controllerを使います。
Q:フォームを送信したあとにリロードすると、もう一度POSTされてしまいます。どうすればいいですか?
それは「二重送信」と呼ばれる現象です。POSTのあとにredirectを使うことで、フォームの再送信を防げます。
Q:Modelにデータを渡したのに画面に表示されません。
テンプレート側でth:text="${変数名}"を正しく記述しているか確認してください。また、Modelのキー名とテンプレートの変数名が一致しているかも重要です。
Q:HTMLファイルが見つからないというエラーが出ます。
テンプレートファイルはsrc/main/resources/templatesに配置し、拡張子は.htmlにする必要があります。パスやファイル名が間違っていないか確認してください。
Q:エラーで「405 Method Not Allowed」が出ました。
これは、送信されたメソッド(GETやPOST)に対応する処理がコントローラーに存在しない場合に発生します。@GetMappingや@PostMappingが正しく記述されているかを確認しましょう。
Q:複数のフォームを同じ画面で使いたいです。
フォームごとにアクションURLを分けるか、hiddenフィールドで区別できるように設計すると実現できます。コントローラー側で処理を分ける工夫が必要です。