Skip to main content

リクエストからコントローラへの値の受け渡し(リンク・パラメータ・フォーム)

Webアプリケーションでは、ブラウザからサーバに「値」を送る場面が頻繁にある。 この章では、リンク・クエリパラメータ・パスパラメータ・フォームを用いて、値をコントローラに渡す方法を学ぶ。 実際のURLの仕組みやフォーム送信の流れを理解し、入力値をサーバ側で処理できるようになることを目指す。

学習のゴール

  • クエリパラメータを @RequestParam で受け取れる
  • パスパラメータを @PathVariable で受け取れる
  • パスパラメータとクエリパラメータの違いと使い分けを理解できる
  • HTMLフォームを使ってPOSTで値を送信し、コントローラで受け取れる
  • フォームオブジェクトを定義して、複数の入力項目をまとめて扱える
  • URLやフォーム送信を通して、リクエストから値を安全かつ整理された形で取得できる

クエリパラメータによる値の受け渡し

URLの「?」以降を クエリパラメータ と呼ぶ。 形式は ?key=value であり、複数の場合は & でつなぐ。

例:

http://localhost:8080/show?user=Taro
http://localhost:8080/show?user=Taro&age=20

なお、入れ替えても同じ意味になる。

http://localhost:8080/show?age=20&user=Taro

クエリパラメータとコントローラの対応

http://localhost:8080/show?user=Taro
└─── @GetMapping("/show") に対応
└─── user=Taro が @RequestParam("user") に渡される

コントローラで受け取るコード例

@Controller
public class ShowController {
@GetMapping("/show") // /show へのGETリクエストを処理する
public String show(
@RequestParam("user") String user, // ?user=... の値を受け取る
@RequestParam("age") int age // ?age=... の値を受け取る
) {
System.out.println(user + " さんは " + age + " 歳です。");
return "display"; // templates/display.html
}
}
  • @RequestParam("user")?user=... の値を受け取る
  • @RequestParam("age")?age=... の値を int 型で受け取る
型変換エラーに注意

@RequestParam("age") int age と定義した場合、URLに ?age=abc など数字以外の文字列が来ると Spring は自動変換に失敗して 400 Bad Request を返す。

  • intInteger … 数値以外が来るとエラー
  • String … 何でも受け取れる(自分でバリデーションが必要)

不正な入力を許容したい場合は String で受け取り、アプリ側でチェックする。

🛠️ ハンズオン演習(手順つき体験)に進む 🎯 練習問題(自力で挑戦)に進む


パスパラメータによる値の受け渡し

URLのパスに直接値を埋め込む方法を パスパラメータ と呼ぶ。

例:

http://localhost:8080/users/1

パスパラメータとコントローラの対応

http://localhost:8080/users/1
└─── {id} に対応

コントローラで受け取るコード例

@Controller
public class UserDetailController {
@GetMapping("/users/{id}") // /users/1, /users/2 などに対応
public String detail(
@PathVariable("id") int id // {id} の値をint型で受け取る
) {
System.out.println("ユーザーIDは " + id + " です。");
return "user-detail"; // templates/user-detail.html
}
}

クエリパラメータとパスパラメータの使い分け

どちらも「値をサーバに渡す方法」だが、役割や用途が異なる。

パスパラメータ

  • どのリソースを指定するか を表すときに使う
  • URLそのものが「異なるページ」として扱われる
  • 例: 商品詳細ページ
    • https://shop.example.com/items/1
    • https://shop.example.com/items/2
  • /items/1/items/2別の商品ページ
  • キャッシュ:URLが固定なのでキャッシュが効きやすい
  • SEO:検索エンジンは異なるURLを別ページとして評価するため、個別の商品や記事に最適

クエリパラメータ

  • どのように表示するか、どの条件で検索するか を表すときに使う
  • URLは同じページで、表示内容だけが変わる
  • 例: 商品検索
    • https://shop.example.com/items?category=books&sort=price_asc
    • https://shop.example.com/items?category=music&sort=price_desc
  • /items?category=books&sort=price_asc/items?category=music&sort=price_desc同じ検索ページ
  • キャッシュ:パラメータの組み合わせが無数にあるため、キャッシュが効きにくい
  • SEO:検索エンジンからは「同じ検索ページの派生」と見なされやすく、条件ごとに個別ページとして強く評価されにくい
使い分けの基本ルール

「リソース=パスパラメータ」「条件=クエリパラメータ」が基本ルール

  • パスパラメータ:リソースを一意に特定するために使う(ユーザーID、商品IDなど)
  • クエリパラメータ:表示条件や検索オプションを指定するために使う(検索キーワード、ページ番号など)

フォームによる値の受け渡し

HTMLフォームを使って値を入力し、サーバに送る場合は通常 POSTリクエスト が使われる。 そのためコントローラ側では @PostMapping を用いる。

フォームの例

<form action="/submit" method="post"> <!-- /submit にPOSTで送信 -->
<label>名前: <input type="text" name="username"></label>
<label>年齢: <input type="number" name="age"></label>
<button type="submit">送信</button>
</form>

コントローラで受け取る例(RequestParamを使う)

@Controller
public class SubmitController {
@PostMapping("/submit") // /submit へのPOSTリクエストを処理
public String submit(
@RequestParam("username") String username, // フォームの name="username" の値を受け取る
@RequestParam("age") int age // フォームの name="age" の値を受け取る
) {
System.out.println("こんにちは " + username + " さん(" + age + "歳)");
return "result"; // templates/result.html
}
}

フォームオブジェクトを使った受け取り

入力項目が増えると @RequestParam を1つずつ書くのは大変。 Springでは フォームオブジェクト を定義し、まとめて受け取るのが一般的。

フォームオブジェクトの置き場所

  • 通常は formdto といった専用のパッケージに配置する
src/main/java/com/example/demo/
├ controller/ … コントローラ
├ form/ … フォームオブジェクトを置く
│ └ UserForm.java
└ service/ … ビジネスロジック

フォームオブジェクトの例

UserForm.javajava
package com.example.demo.form;
public class UserForm {
private String username;
private int age;
// getter / setter を必ず用意
public String getUsername() { return username; }
public void setUsername(String username) { this.username = username; }
public int getAge() { return age; }
public void setAge(int age) { this.age = age; }
}

HTMLフォームとフィールドの対応

<form action="/submit" method="post">
<input type="text" name="username"> <!-- UserForm.username に対応 -->
<input type="number" name="age"> <!-- UserForm.age に対応 -->
<button type="submit">送信</button>
</form>
  • <input name="username">UserFormusername フィールドに自動で値が入る
  • <input name="age">UserFormage フィールドに自動で値が入る

コントローラでフォームオブジェクトを使う例

SubmitController.javajava
package com.example.demo.controller;
import com.example.demo.form.UserForm;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PostMapping;
@Controller
public class SubmitController {
@PostMapping("/submit")
public String submit(UserForm form, Model model) {
model.addAttribute("message", "こんにちは "
+ form.getUsername() + " さん(" + form.getAge() + "歳)");
return "result";
}
}
  • フォームの <input>name 属性とオブジェクトのフィールド名が一致していれば、自動で値がセットされる
  • 入力項目が増えても引数がシンプルに保てるため、保守性が高い

本章のまとめ

  • クエリパラメータは ?key=value 形式で渡し、複数は & でつなぐ
  • @RequestParam("key") で受け取れる
  • パスパラメータは /path/{id} の形式で、@PathVariable で受け取れる
  • 使い分け:リソースの識別はパスパラメータ、条件指定はクエリパラメータ
  • フォーム送信はPOSTであり、@PostMapping で処理する
  • フォームオブジェクトを使うと、<input name="..."> とフィールド名を対応させてまとめて受け取れる
  • 次章では、コントローラからビューへの値の渡し方と、Thymeleafの使い方を学ぶ

よくある質問

Q. @RequestParam で型変換エラーが起きないようにするには?

A. int の代わりに Integer を使い、required = falsedefaultValue を組み合わせると柔軟に扱える。

@RequestParam(name = "age", required = false, defaultValue = "0") int age

Q. パスパラメータで @PathVariable を使うとき、変数名を省略できますか?

A. Java 8以降でコンパイルオプション -parameters が有効な場合、メソッドの変数名と {id} が一致していれば省略できる。 Spring Bootのデフォルト設定では省略可能な場合が多いが、明示的に書くのが推奨される。

// 省略形(推奨されないが動く場合がある)
@PathVariable int id

// 明示的な書き方(推奨)
@PathVariable("id") int id

Q. フォームオブジェクトにgetterとsetterは必須ですか?

A. 必須である。Springはフォームオブジェクトに値をセットするときにsetterを呼び出す。 setterが存在しないと、フォームから送られた値がオブジェクトに入らないため、すべて null0 になってしまう。


Q. POSTとGETではどちらがセキュリティ上安全ですか?

A. POSTの方が一般的に安全である。GETではパラメータがURLに含まれるため、 ブラウザの履歴・アクセスログ・リファラーヘッダーに値が残りやすい。 パスワードなどの秘密情報は必ずPOSTで送信する。


🛠️ハンズオン演習(手順つき体験)

クエリパラメータによる値の受け渡し

パスパラメータによる値の受け渡し

フォームによる値の受け渡し

🎯演習問題(自力で挑戦)

クエリパラメータによる値の受け渡し

パスパラメータによる値の受け渡し

フォームによる値の受け渡し


Webアプリケーションにおける「リクエストパラメータ」の説明として、最も適切なものを選べ。

正解

D. URLの`?`以降に付加されるキーと値のペア(クエリ文字列)や、フォームから送信されるデータのこと

解説

リクエストパラメータとは、HTTPリクエストとともにサーバーに送られるデータである。

  • GETリクエスト: URL末尾に ?name=value の形式でURLに付加される 例:/search?keyword=spring&page=2
  • POSTリクエスト: リクエストボディに格納される(フォームデータ)

Springでは @RequestParam アノテーションでこれらのパラメータをメソッドの引数として受け取ることができる。

SpringMVCの @RequestParam アノテーションの役割として、最も適切なものを選べ。

正解

B. URLのクエリパラメータやフォームデータを、コントローラのメソッドの引数として受け取るためのアノテーション

解説

@RequestParam はURLのクエリパラメータまたはフォームデータをコントローラのメソッドの引数にバインドするアノテーションである。

使用例:

// /search?keyword=spring にアクセスした場合
@GetMapping("/search")
public String search(@RequestParam String keyword) {
    // keyword = "spring"
}

オプション引数:

  • required = false: パラメータを省略可能にする(省略時は null)
  • defaultValue = "値": 省略時のデフォルト値を指定する

SpringMVCの @PathVariable アノテーションの役割として、最も適切なものを選べ。

正解

A. URLパス内の変数部分(`{id}`など)をメソッドの引数として受け取るためのアノテーション

解説

@PathVariable はURLパスの一部として埋め込まれた変数を受け取るアノテーションである。

使用例:

// /products/5 にアクセスした場合
@GetMapping("/products/{id}")
public String detail(@PathVariable Long id) {
    // id = 5
}

RESTful APIのように /users/1 の形式でリソースを識別する際によく使われる。

@RequestParam(クエリ文字列)との違い:

  • @PathVariable: URLパス内に埋め込む → /products/5
  • @RequestParam: クエリ文字列として付加 → /products?id=5

/search?keyword=xxx のクエリパラメータを受け取るメソッドを完成させよ。

@GetMapping("/search") public String search(
String keyword, Model model) { model.addAttribute("keyword", keyword); return "search/result"; }

解答例
@GetMapping("/search") public String search(@RequestParam String keyword, Model model) { model.addAttribute("keyword", keyword); return "search/result"; }
解説

@RequestParam をメソッドの引数の前に付けることで、URLのクエリパラメータを受け取ることができる。

/search?keyword=spring というURLにアクセスすると、keyword 引数に "spring" が渡される。

複数のパラメータも受け取れる:

public String search(
    @RequestParam String keyword,
    @RequestParam int page) { ... }

/products/{id} のパス変数を受け取るメソッドを完成させよ。

@GetMapping("/products/{id}") public String detail(
Long id, Model model) { model.addAttribute("id", id); return "products/detail"; }

解答例
@GetMapping("/products/{id}") public String detail(@PathVariable Long id, Model model) { model.addAttribute("id", id); return "products/detail"; }
解説

@PathVariable を使うことでURLパスの変数部分({id})をメソッドの引数として受け取ることができる。

URLが /products/5 の場合、id 引数に 5 が渡される。

@GetMapping のパスパターン内の {変数名} と引数名を一致させる必要がある。

パスパラメータ(@PathVariable)とクエリパラメータ(@RequestParam)の使い分けとして、最も適切なものを選べ。

正解

C. パスパラメータはリソースの識別(`/users/1`)に使い、クエリパラメータは絞り込み・ソートなどの修飾情報(`?sort=name`)に使うのが一般的である

解説

パスパラメータとクエリパラメータの使い分けの一般的な指針:

  • パスパラメータ/users/1): リソースを一意に識別する → @PathVariable で受け取る
  • クエリパラメータ?page=2&sort=name): 絞り込み・ソート・ページングなどの補助情報 → @RequestParam で受け取る

例:

  • 特定ユーザーの取得: GET /users/1(パスパラメータ)
  • ユーザー一覧の絞り込み: GET /users?role=admin(クエリパラメータ)

フォームオブジェクト(UserFormクラス:nameemailフィールドを持つ)でフォームデータをまとめて受け取るメソッドを完成させよ。

@PostMapping("/register") public String register(
form, Model model) { String name =
; model.addAttribute("name", name); return "register/complete"; }

解答例
public String register(UserForm form, Model model) { String name = form.getName(); }
解説

フォームオブジェクト(フォームクラス)を使うと、複数のフォームフィールドをまとめて受け取ることができる。

フォームクラスのフィールド名とHTMLのname属性が一致していれば、Springが自動的にバインドする。

public class UserForm {
    private String name;
    private String email;
    // getter/setter
}

@RequestParam を複数使うより、フォームオブジェクトの方が管理しやすい。

以下のコードで /items?category=books にアクセスしたとき、pagecategory の値として正しいものを選べ。

@GetMapping("/items")
public String search(
@RequestParam(defaultValue = "1") int page,
@RequestParam(required = false) String category,
Model model) {
model.addAttribute("page", page);
model.addAttribute("category", category);
return "items/list";
}

正解

B. `page`は`1`、`category`は`"books"`

解説

@RequestParam(defaultValue = "1") は、パラメータが指定されていない場合のデフォルト値を設定する。

/items?category=books では page が指定されていないため、デフォルト値の 1 が使われる。

@RequestParam(required = false) はパラメータを省略可能にし、指定されない場合は null になるが、 category=books が指定されているため "books" が渡される。

  • page → 指定なし → デフォルト値 1
  • category → 指定あり → "books"

keyword(任意・省略可)と category(省略時は "all")のクエリパラメータを受け取るメソッドを完成させよ。

@GetMapping("/products") public String list( @RequestParam(
) String keyword, @RequestParam(
) String category, Model model) { return "products/list"; }

解答例
@RequestParam(required = false) String keyword, @RequestParam(defaultValue = "all") String category
解説

@RequestParam のオプション設定:

  • required = false: パラメータを省略可能にする。省略時の値は null
  • defaultValue = "値": 省略時のデフォルト値を指定する。設定すると required は自動的に false になる

使い分け:

  • 省略可能で null チェックが必要な場合: required = false
  • 省略時にデフォルト値を使う場合: defaultValue = "値"