@PathVariableの使い方を完全ガイド!URLの一部を取り出す方法をSpring Bootで学ぼう
新人
「先輩、Spring BootでURLの一部をJavaの変数として使う方法ってあるんですか?」
先輩
「あるよ。@PathVariableっていうアノテーションを使うと、URLの中から特定の部分だけを取り出して使えるんだ。」
新人
「それって、たとえばユーザーIDとか商品番号みたいなものをURLから取得するってことですか?」
先輩
「その通り。ユーザーIDがURLの一部に含まれているようなときに、とても便利なんだ。具体的にどう使うか、順番に説明するね。」
1. @PathVariableとは何か?
@PathVariableは、Spring Bootのコントローラーメソッドで使用されるアノテーションのひとつです。HTTPリクエストのURLの一部を、そのままJavaの変数として取り出すことができます。たとえば、「/user/123」のようなURLがあったときに、「123」の部分を取り出して、コントローラ内で使いたい場合に使います。
Spring MVCでは、リクエストを処理するために、URLとメソッドをマッピングします。その際、@PathVariableを使うことで、URLに含まれている可変の値をメソッドの引数として受け取ることができます。これにより、より柔軟なルーティングが可能になります。
Spring Boot + GradleのPleiades環境で開発している場合でも、特別な設定は不要で、すぐに@PathVariableを使ったURL処理ができます。とてもシンプルで、初心者にも理解しやすい構文なので、まずは基本から覚えておきましょう。
2. URLの一部を取り出す仕組みの概要
Spring Bootの@PathVariableを使うと、URLの中に埋め込まれた情報を簡単に取り出すことができます。これを実現する仕組みは、「パスパラメータ」と呼ばれるものです。URLの中に「{変数名}」という形式で指定しておくと、その部分がリクエスト時に変動しても、Springが自動的に中身を取り出してくれるのです。
たとえば、次のようなURLを考えてみましょう。
http://localhost:8080/product/5678
この場合、「5678」という数値は商品番号です。この番号をJavaのメソッドの中で使いたいとき、@PathVariableを使えば自動で取得できます。
取り出した値は、Javaの変数として利用できるため、そのまま画面表示やデータベース検索、ログ出力などに活用できます。
3. Spring MVCにおけるパスパラメータの基本的な使い方
それでは、実際に@PathVariableを使ったSpring Bootのコントローラーのコード例を見てみましょう。ここでは、URLに含まれるユーザーIDを受け取って、そのIDを画面に表示するだけのシンプルな処理を実装します。
まず、次のようなコントローラークラスを作成します。
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.PathVariable;
@Controller
public class UserController {
@GetMapping("/user/{id}")
public String showUser(@PathVariable String id, Model model) {
model.addAttribute("userId", id);
return "user-view";
}
}
このコードでは、@GetMapping("/user/{id}")の部分でURLの一部に{id}を指定しています。この{id}にマッチする値があれば、それが@PathVariable String idとして引数に渡されます。
そして、受け取ったIDをModelに追加して、user-view.htmlというHTMLテンプレートに渡します。テンプレート側では、userIdという変数を使ってIDを表示できます。
URLにアクセスすると、たとえば次のようになります。
http://localhost:8080/user/abc123
このとき、abc123がidにセットされ、ビューで表示されるという流れになります。
4. 実際に@PathVariableを使ったサンプルコード
ここでは、@PathVariableを使ってURLの一部を受け取り、それをHTMLページで表示するサンプルを紹介します。Pleiadesで作成したSpring Boot + Gradleプロジェクトを前提にしています。まずはコントローラクラスから見ていきましょう。
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.PathVariable;
@Controller
public class ProductController {
@GetMapping("/product/{productId}")
public String showProduct(@PathVariable String productId, Model model) {
model.addAttribute("productId", productId);
return "product-detail";
}
}
このコードでは、/product/{productId}というURLにアクセスすると、その{productId}に指定された文字列がJavaの変数productIdとして受け取られます。そして、その値をModelに追加して、ビューで使えるようにしています。
たとえば、次のようなURLでアクセスした場合:
http://localhost:8080/product/A001
「A001」がそのまま変数に入り、product-detail.htmlで使えるようになります。このように、@PathVariableを使うことで、URLから必要な情報を取り出して画面に表示したり、処理に使ったりすることができます。
5. 複数のパスパラメータを使う場合の書き方
@PathVariableは、ひとつだけでなく、複数のパスパラメータを同時に使うこともできます。たとえば、「注文ID」と「商品ID」の両方をURLから取得したい場合は、次のように書くことができます。
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.PathVariable;
@Controller
public class OrderController {
@GetMapping("/order/{orderId}/item/{itemId}")
public String showOrderItem(@PathVariable String orderId, @PathVariable String itemId, Model model) {
model.addAttribute("orderId", orderId);
model.addAttribute("itemId", itemId);
return "order-item";
}
}
この例では、URLの中に「/order/{orderId}/item/{itemId}」という形で2つのパスパラメータを指定しています。それぞれの値は、対応するJavaの引数orderIdとitemIdに自動で渡されます。
たとえば次のようなURLにアクセスした場合:
http://localhost:8080/order/202307/item/XYZ01
この場合、「202307」は注文IDとして、そして「XYZ01」は商品IDとして、それぞれの変数にセットされます。そして、それらを画面に表示したり、データベースの検索に使うことができます。
このように、複数の値を同時に受け取りたいときも、@PathVariableを使えば柔軟に対応できます。ルートの構造は少し長くなりますが、処理の見通しがよくなるため、設計上も非常に有効です。
6. コントローラクラス内での@PathVariableの動き
それでは、@PathVariableを使ったときに、Spring MVCの中でどのように処理が行われるのか、簡単に流れを確認しておきましょう。Spring Bootは、URLに対応するメソッドを自動で判断して、適切な値を渡す仕組みを持っています。
たとえば、次のような処理の流れになります:
- ブラウザやアプリがURLにアクセスします(例:
/user/abc123)。 - Spring Bootは、
@GetMappingなどのルーティング設定から、どのメソッドを実行するかを判断します。 - URLに含まれる
{id}の部分と、メソッドの@PathVariable String idが対応して、自動的に値が渡されます。 - メソッド内で受け取った変数を使って、画面表示用のModelにデータを追加します。
- ビュー名を返すと、対応するHTMLテンプレートが表示されます。
つまり、開発者がやることは、URLのパターンを{}で書いて、メソッドの引数に@PathVariableをつけるだけです。あとはSpring MVCが自動でマッピングしてくれるので、URLの中にある情報を簡単に扱えるようになるのです。
また、変数名を一致させることが基本ですが、異なる名前にしたい場合は次のように書けます。
@GetMapping("/user/{uid}")
public String showUser(@PathVariable("uid") String id, Model model) {
model.addAttribute("userId", id);
return "user-view";
}
このように、URL側の変数名とメソッド引数の名前が違っても、@PathVariable("uid")と書くことで問題なく使えます。
初心者のうちは、変数名を揃えておく方が覚えやすいですが、ゆくゆくはこういった柔軟な書き方も使いこなせるようになっていくと良いでしょう。
7. @PathVariableを使う上での注意点
@PathVariableを使うと、Spring BootでURLの一部を簡単に取り出せますが、書き方や構成を間違えるとエラーになることがあります。ここでは、初心者がよく間違えるポイントと、実際のエラー例を紹介します。
まず、URLのパスとメソッドの引数の変数名が一致していない場合、次のようなエラーが発生します。
@GetMapping("/user/{id}")
public String getUser(@PathVariable String userId, Model model) {
model.addAttribute("userId", userId);
return "user-view";
}
このコードでは、URL側が{id}なのに、メソッド引数がuserIdになっているため、Spring Bootは自動でマッピングできず、リクエスト処理時にエラーになります。
このようなときは、@PathVariable("id")と明示的に書く必要があります。
@GetMapping("/user/{id}")
public String getUser(@PathVariable("id") String userId, Model model) {
model.addAttribute("userId", userId);
return "user-view";
}
もうひとつの注意点は、URLパターンに含まれる値が足りない場合です。たとえば、次のようなコントローラーがあるとします。
@GetMapping("/product/{id}")
public String showProduct(@PathVariable String id, Model model) {
model.addAttribute("id", id);
return "product-view";
}
このURLにアクセスせず、/productだけでアクセスした場合、Spring Bootはマッピングに失敗して「404エラー」になります。URLに必ず/product/何かという形でアクセスしなければなりません。
これらのように、@PathVariableを使うときは「URLパターンと変数名を一致させる」「必要な値をURLに含める」というルールを守ることが大切です。
8. @RequestParamとの違いと使い分け方
Spring Bootには、URLの一部から値を取り出す@PathVariableのほかに、クエリパラメータから値を取得する@RequestParamというアノテーションもあります。
この2つはよく似ていますが、使う場面が異なります。ここでそれぞれの違いを確認しておきましょう。
■ @PathVariable:URLの一部に含まれる値を使いたいとき
http://localhost:8080/user/123
@GetMapping("/user/{id}")
public String getUser(@PathVariable String id, Model model) {
model.addAttribute("userId", id);
return "user-view";
}
■ @RequestParam:URLの末尾にあるクエリ文字列を使いたいとき
http://localhost:8080/user?id=123
@GetMapping("/user")
public String getUser(@RequestParam String id, Model model) {
model.addAttribute("userId", id);
return "user-view";
}
@PathVariableはルーティングに組み込まれているのに対し、@RequestParamはオプションとして使えるケースが多いです。どちらもURLから値を取得しますが、意味が違うため、目的に応じて使い分けることが大切です。
たとえば、「ユーザーIDなどURLの構造の一部として固定的に扱いたい情報」は@PathVariable、「検索条件やソートなどの任意の情報」は@RequestParamが適しています。
9. 初心者向けのよくある質問とその答え(FAQ)
Q:@PathVariableの引数がnullになることはありますか?
A:通常、URLに値が含まれていれば@PathVariableはnullになりません。ただし、URLの構造が間違っていたり、パスに対応する部分が指定されていないと、メソッドが呼ばれずに404エラーになります。
Q:@PathVariableで受け取る型はString以外も使えますか?
A:はい、intやlongなどの数値型も使えます。ただし、URLの値がその型に変換できないと、400 Bad Requestエラーになります。初心者のうちはまずStringで受け取るのが安全です。
Q:@PathVariableと@RequestParamを一緒に使えますか?
A:はい、どちらも同じメソッド内で使うことができます。たとえば次のように、パスパラメータとクエリパラメータを同時に受け取れます。
@GetMapping("/user/{id}")
public String getUser(@PathVariable String id, @RequestParam(required = false) String sort, Model model) {
model.addAttribute("userId", id);
model.addAttribute("sort", sort);
return "user-view";
}
この場合、「/user/abc123?sort=name」のようなURLでアクセスすれば、両方の値が取得できます。
Q:URLの一部を取り出す方法が複数あるのはなぜですか?
A:Webのリクエストには、パスパラメータとクエリパラメータの2種類の形式があるからです。それぞれに適したアノテーションが用意されているため、状況に応じて選択できるようになっています。
Q:@PathVariableはPOSTメソッドでも使えますか?
A:はい、POSTやPUT、DELETEでも使えます。ただし、GET以外のメソッドを使うには、フォームやJavaScriptから明示的に送信する必要があります。基本的な使い方はGETと同じです。