【Spring Boot】RequestBody が受け取れないときの原因をやさしく解説

Java入門・実践
スポンサーリンク
スポンサーリンク

はじめに

Spring Boot で API を作っていると、
「@RequestBody が null になる…」
「JSON が DTO に入らない…」
というつまずきがよく起きます。

実務でも頻出するポイントで、
原因を知っておくだけでトラブルシューティングが一気に楽になります。

この記事では、RequestBody が受け取れないときの原因を
やさしく・実務で役立つ形 で整理していきます。

まずはよくあるコードを見て、そこから少しずつ理解していきましょう。

まずはコードを確認

Java
@PostMapping("/users")
public String createUser(@RequestBody UserRequest request) {
    return "created";
}

このようなコードで、
request が null になる / フィールドが入らない
という問題が起きることがあります。

RequestBody が受け取れないときの主な原因

Content-Type が application/json になっていない

最も多い原因です。

POST のヘッダーが

Content-Type: application/json

になっていないと、Spring は JSON と認識しません。

よくある間違い

  • Content-Type: text/plain
  • Content-Type: application/x-www-form-urlencoded
  • Content-Type がそもそも付いていない

対策

API クライアント(Postman / curl / フロント)で
必ず application/json を指定します。

JSON の形式が間違っている

JSON が正しくないと、DTO にマッピングできません。

よくある間違い

  • ダブルクォートが抜けている
  • カンマの付け忘れ
  • フィールド名が DTO と一致していない

例:NG

JSON
{ name: "taro", age: 20 }

例:OK

JSON
{ "name": "taro", "age": 20 }

DTO のフィールド名が JSON と一致していない

Spring はフィールド名を見てマッピングします。

NG

Java
private String userName; // JSON は name
JSON
{ "name": "taro" }

対策

  • フィールド名を JSON に合わせる
  • どうしても違う場合は @JsonProperty を使う
Java
@JsonProperty("name")
private String userName;

getter / setter がない(Lombok の付け忘れ)

DTO に getter / setter がないと値が入りません。

よくある例

Java
public class UserRequest {
    private String name;
    private int age;
}

→ 値が入らない

対策

Java
@Data
public class UserRequest {
    private String name;
    private int age;
}

Lombok を使うか、手動で getter/setter を書きます。

@RequestBody を付け忘れている

意外と多いパターンです。

Java
public String createUser(UserRequest request) // ← @RequestBody がない

→ Spring はボディを読みません。

POST ではなく GET を使っている

GET はボディを読みません。

NG

Java
@GetMapping("/users")
public String createUser(@RequestBody UserRequest request)

対策

POST / PUT / PATCH を使います。

フロント側が JSON を送っていない

JavaScript の fetch でよくあるミスです。

NG

JavaScript
fetch("/users", {
  method: "POST",
  body: { name: "taro" } // JSON.stringify していない
});

OK

JavaScript
fetch("/users", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ name: "taro" })
});

HttpMessageConverter が動いていない

Spring が JSON を変換する仕組みです。

  • Jackson が依存に入っていない
  • WebMvcConfigurer で無効化してしまった

などが原因になります。

対策

spring-boot-starter-web が入っていれば基本 OK です。

あわせて知っておきたいポイント

Validation と組み合わせるとエラーがわかりやすい

Java
public String create(@Valid @RequestBody UserRequest request)

ログを出すと原因が見つけやすい

logging.level.org.springframework.web=DEBUG

Postman / curl でまず動作確認する

フロントの問題か API の問題か切り分けできます。

使うときに気をつけたいこと

Content-Type を必ず確認する

最初に見るべきポイントです。

DTO のフィールド名を揃える

JSON と一致していないと値が入りません。

GET にボディを付けない

仕様上は非推奨です。

まとめ

RequestBody が受け取れない原因は、
「Content-Type」「JSON の形式」「DTO の定義」
のどれかであることがほとんどです。

  • Content-Type が application/json か
  • JSON が正しい形式か
  • DTO のフィールド名が一致しているか
  • getter/setter があるか
  • @RequestBody を付けているか

難しく聞こえますが、
「JSON → DTO の変換がどこで止まっているか」
を順番に見ていけば必ず解決できます。


decopon
decopon

RequestBody のつまずきは、誰もが一度は経験するポイントです。
原因を知っておくだけで、API のデバッグがぐっと楽になります。
あなたの開発が、今日より少しだけ楽になりますように。

moco
moco

JSON が DTO に入らないときって、迷子みたいでかわいそうだね…ちゃんと迎えに行ってあげたい…

コメント

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