SpringコントローラにおけるJSONペイロードの受信失敗と解決策

フロントエンドから送信されたパラメータがバックエンドで検出されない主な原因は、コントローラのメソッド引数に対するデータバインド設定が不足している場合です。特に、JSON形式のリクエストボディを処理する際に @RequestBody アノテーションが省略されているケースがほとんどです。

修正前後のコントローラ定義

以下はパラメータが正しくマッピングされない状態と、修正後の状態を比較した例です。

// 修正前:引数にアノテーションがなく、フィールドがnullになる
@PostMapping("/api/members/register")
public ApiResponse createMember(MemberDto info) {
    return ApiResponse.success();
}
// 修正後:リクエストボディを明示的にJSONからオブジェクトへ変換
@PostMapping("/api/members/register")
public ApiResponse createMember(@RequestBody MemberDto info) {
    return ApiResponse.success();
}

アノテーションの動作原理とHTTPメソッドの制約

@RequestBody は、HTTPリクエストのボディ部分に格納されたデータを読み取り、指定したJavaオブジェクトにデシリアライズする役割を果たします。GETリクエストの仕様上ボディが存在しないため、このアノテーションを有効に機能させるにはPOSTやPUTメソッドを用いる必要があります。

クエリパラメータとの併用規則

Spring MVCでは、同一メソッド内で @RequestBody@RequestParam を同時に宣言可能です。ただし、以下の制約を遵守する必要があります。

  • @RequestBody はメソッドあたり最大1つまでしか設定できない。
  • @RequestParam は複数設定可能であり、URLのクエリ文字列や application/x-www-form-urlencoded データから値を抽出する。

両者を併用する場合、Spring MVCはリクエストボディを @RequestBody が担当し、それ以外のキーバリュー形式のデータを @RequestParam が処理します。したがって、フロントエンドが application/json ヘッダーでデータを送信している場合は必ず @RequestBody を付与し、フォーム送信やURLパラメータの場合は @RequestParam またはアノテーション省略(デフォルトバインド)で対応します。

パラメータ名の厳密性とデフォルト挙動

@RequestParam("keyName") を明示した場合、クライアント側は必ず該当キーを含める必要があります。値が空でもキー名が存在しない場合は、required=false を設定しない限りHTTP 400エラーが返却されます。一方、アノテーションを省略した場合は、フレームワークが引数名とリクエストパラメータ名を自動照合し、一致しない場合でもエラーを発生させずに処理を継続します。

なお、Spring Cloud Feignなどの宣言的HTTPクライアントを利用する場合、アノテーションなしの引数は自動的に @RequestBody として扱われる仕様となっているため、ローカルのRESTコントローラ実装とはパラメータ解決のデフォルト挙動が異なる点に留意が必要です。

タグ: spring-mvc @RequestBody JSON-Deserialization rest-api Feign-Client

8月1日 00:17 投稿