前回は、Controller(コントローラ)を使ってURLとメソッドを結びつけるルーティングの基本を学び、固定の文字列を返すAPIを作成しました。
しかし、実際のWebアプリケーションでは、ユーザーがフォームに入力したり、URLに特定の情報を付け加えたりして、動的なデータをサーバーに送ってきます。
今回は、Controllerのメソッドで、これらのリクエストデータ(パラメータ、パス変数など)をどのように受け取って処理するかを詳しく学びます。
1. パラメータの受け取り方(3つの主要な方法)
Spring Web MVCでは、主に以下の3つの方法でクライアント(ユーザーのブラウザなど)から送られてくるデータを受け取ります。
1-1. @RequestParam:クエリパラメータの取得
URLの末尾に ?key=value&key2=value2 の形式で付加されるデータをクエリパラメータと呼びます。これを受け取るには @RequestParam を使用します。
| URLの形式 | http://localhost:8080/search?keyword=Java&limit=10 |
Java
@RestController
@RequestMapping("/search")
public class SearchController {
// @RequestParamで、URLの「keyword」と「limit」の値を受け取る
// String keyword = "Java", int limit = 10 が注入される
@GetMapping
public String search(@RequestParam String keyword,
@RequestParam(required = false, defaultValue = "5") int limit) {
// required = false: パラメータが省略されてもOK
// defaultValue: パラメータがない場合の初期値を設定
return keyword + "で検索を開始します。表示件数は " + limit + " 件です。";
}
}
1-2. @PathVariable:パス変数(URLの一部)の取得
リソース(データ)を一意に識別するために、URLのパスの一部としてデータを埋め込む方法です。RESTful APIではこの形式が多用されます。これを受け取るには @PathVariable を使用します。
| URLの形式 | http://localhost:8080/users/105 |
Java
@RestController
@RequestMapping("/users")
public class UserController {
// URLの {id} 部分を @PathVariable でキャプチャする
@GetMapping("/{id}")
public String getUserDetail(@PathVariable("id") int userId) {
// int userId = 105 が注入される
return "ユーザーID: " + userId + " の詳細情報を表示します。";
}
// @PathVariable の引数名と変数名が同じ場合は、引数名を省略できる
@GetMapping("/{category}/{itemId}")
public String getItem(@PathVariable String category, @PathVariable int itemId) {
return "カテゴリ: " + category + ", 商品ID: " + itemId + " を取得しました。";
}
}
2. フォームやJSONデータの受け取り方(@RequestBody と DTO)
ユーザーがログインフォームを送信したり、外部システムがJSONデータを送ってきたりする場合、データはリクエストボディ(HTTPリクエストの本体)に含まれています。
このボディ全体を受け取り、Javaオブジェクトに変換するには、@RequestBody を使います。
2-1. DTO(Data Transfer Object)の利用
リクエストボディのデータを扱う際は、そのデータの構造を定義した専用のJavaクラス(DTO: Data Transfer Object)を作成するのが一般的です。
DTOの定義(Lombok利用)
Java
// DTO(データの入れ物)
// @DataはLombokのアノテーションで、getter/setterなどを自動生成する
@Data
public class LoginForm {
private String username;
private String password;
}
2-2. @RequestBody による注入
Controllerのメソッドで、このDTOを引数として受け取り、@RequestBody を付けます。
Java
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
// ... その他のimport
@RestController
@RequestMapping("/auth")
public class AuthController {
// HTTP POSTリクエストで、リクエストボディをLoginFormオブジェクトとして受け取る
@PostMapping("/login")
public String login(@RequestBody LoginForm form) {
// formオブジェクトにJSONデータが自動的にマッピングされる
if ("admin".equals(form.getUsername()) && "password".equals(form.getPassword())) {
return "ログイン成功: " + form.getUsername();
} else {
return "ログイン失敗";
}
}
}
Spring Bootは、リクエストボディがJSON形式の場合、内部でJSONパーサー(Jacksonなど)を使い、自動で対応するフィールドにデータをマッピングしてくれます。
3. 受け取ったデータのバリデーション(次回予告)
データを受け取った後、そのまま使うのは危険です。例えば、「ユーザー名は必須」「パスワードは8文字以上」といった**入力チェック(バリデーション)**を行う必要があります。
上記のコード例では、バリデーションが省略されていますが、業務システムではこのバリデーションこそが非常に重要になります。
✅ 本日のまとめ
- クライアントからのデータは、主にクエリパラメータ、パス変数、リクエストボディの3種類で送られてくる。
@RequestParam:URLの末尾(?key=value)のデータを受け取る。@PathVariable:URLのパスの一部(/users/{id})のデータを受け取る。@RequestBody:HTTPリクエストの本体(JSONやXMLなど)を受け取り、DTOというJavaオブジェクトに自動でマッピングする。
🔔 次回予告
今回、ユーザーからデータを受け取る方法を学びましたが、受け取ったデータが「正しい形」をしている保証はありません。データが空だったり、文字数がオーバーしていたりすると、システムが予期せぬエラーを起こす可能性があります。
次回は、Springが提供する強力な機能である Bean Validation を使い、受け取ったDTOに対して「これは正しいデータか?」を自動でチェックし、エラーをハンドリングする方法について学びます。
次回:【第17回】データのバリデーションとエラーハンドリング にご期待ください!


コメント