📩 Spring Framework 講座【第16回】ユーザー入力を処理する!〜リクエストパラメータの受け取り方〜

docs

前回は、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回】データのバリデーションとエラーハンドリング にご期待ください!

コメント

タイトルとURLをコピーしました