Springの@RequestBodyでJSONを受け取る方法を初心者向けに解説!
新人
「先輩、Springでクライアントからデータを受け取るときって、どうやってJSONを扱うんですか?」
先輩
「いい質問だね。Springでは、クライアントから送られてくるJSON形式のリクエストを受け取るには、@RequestBodyというアノテーションを使うんだよ。」
新人
「@RequestBodyって何ですか?JSONってそもそも何かよくわかってなくて…」
先輩
「よし、じゃあまずはその2つを順番に説明していこう!」
1. @RequestBodyとは?
@RequestBodyは、SpringでHTTPリクエストのボディ部分に含まれるデータをJavaオブジェクトに変換するためのアノテーションです。特に、クライアント(ブラウザやアプリなど)から送られてくるJSON形式のデータを受け取るときによく使われます。
たとえば、サーバーにユーザー情報を送信するAPIを作るとき、次のようなJSONがリクエストとして送られてくることがあります。
{
"name": "Taro",
"email": "taro@example.com"
}
このJSONをJavaのクラスに自動的にマッピングするために、@RequestBodyを使います。Springが内部でJacksonというライブラリを使って、自動的にJSONをJavaオブジェクトに変換してくれるのです。
では、実際にどのようにコードを書くのか、簡単な例を見てみましょう。
@Controller
public class UserController {
// クライアントからJSONでユーザー情報を受け取る
@PostMapping("/user")
@ResponseBody
public String createUser(@RequestBody User user) {
return "受け取った名前: " + user.getName() + "、メール: " + user.getEmail();
}
}
// ユーザー情報を表すJavaクラス
public class User {
private String name;
private String email;
// ゲッターとセッターが必要
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
この例では、クライアントが/userにPOSTリクエストを送り、リクエストボディにJSON形式のデータを含めると、@RequestBodyがそのデータをUserクラスのインスタンスに変換してくれます。
変換されたJavaオブジェクトを使って、サーバー側で処理ができるようになるのです。Springが自動的にデシリアライズ(文字列→オブジェクト変換)してくれるので、とても便利ですね。
2. JSONとは?
次に、JSON(ジェイソン)について説明しましょう。JSONは「JavaScript Object Notation」の略で、データをやり取りするための軽量なフォーマットです。人間にも読みやすく、機械でも処理しやすいのが特徴です。
多くのWeb APIでは、クライアントとサーバーの間でデータを交換するのにJSONが使われています。たとえば、スマートフォンのアプリからサーバーにユーザー情報を送るときや、ブラウザでデータを非同期に取得するときなど、あらゆる場面で使われます。
基本的なJSONの構造は、キーと値のペアでできており、次のように記述します。
{
"title": "Spring入門",
"price": 1980,
"stock": true
}
このように、title、price、stockといったキーに、それぞれ文字列・数値・真偽値の値が対応しています。
JSONはとてもシンプルなので、初心者でもすぐに理解できます。Springでは、このJSONデータを@RequestBodyを使って受け取り、Javaのクラスにマッピングすることで、効率よくリクエストを処理できるようになります。
たとえば、JavaScriptやPostmanなどのツールを使って、次のようなリクエストをサーバーに送ることができます。
POST /user HTTP/1.1
Content-Type: application/json
{
"name": "Hanako",
"email": "hanako@example.com"
}
このリクエストをSpringのコントローラで受け取ることで、クライアントからの情報をしっかりとサーバーで受信・処理することができます。
3. HTMLやJavaScriptからJSONをPOST送信する方法
ここでは、実際にブラウザ上のHTMLとJavaScriptを使って、SpringのサーバーへJSONデータをPOSTメソッドで送信する方法を見てみましょう。クライアントからのリクエストには、fetch関数を使うのが一般的です。
以下は、シンプルなHTMLフォームとJavaScriptを組み合わせて、名前とメールアドレスをJSON形式で送信する例です。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>JSON送信フォーム</title>
</head>
<body>
<h2>ユーザー情報送信フォーム</h2>
<form id="userForm">
<label for="name">名前:</label>
<input type="text" id="name" name="name"><br><br>
<label for="email">メール:</label>
<input type="email" id="email" name="email"><br><br>
<button type="submit">送信</button>
</form>
<script>
document.getElementById("userForm").addEventListener("submit", function(event) {
event.preventDefault(); // フォームのデフォルト動作を停止
const data = {
name: document.getElementById("name").value,
email: document.getElementById("email").value
};
fetch("/user", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(data)
})
.then(response => response.text())
.then(result => {
alert("サーバーからのレスポンス:" + result);
})
.catch(error => {
console.error("エラー:", error);
});
});
</script>
</body>
</html>
このHTMLファイルでは、ユーザーがフォームに入力した情報をJSON形式に変換し、/userエンドポイントにPOSTリクエストとして送信します。サーバー側では、Springの@RequestBodyでこのJSONデータを受け取り、処理できます。
4. Springで@RequestBodyを使ってJSONを受け取る実装例
次に、先ほどのHTMLから送られてくるJSONデータを、Spring側でどのように受け取るかを実装例で見ていきましょう。ここでも、@Controllerと@ResponseBodyを使って構成します。
@Controller
public class UserController {
// JSONデータを受け取るPOSTエンドポイント
@PostMapping("/user")
@ResponseBody
public String receiveJson(@RequestBody User user) {
String name = user.getName();
String email = user.getEmail();
return "JSONを受け取りました:名前 = " + name + "、メール = " + email;
}
}
このように、POSTメソッドで送られてきたJSONは、Springが内部で自動的にUserクラスへマッピングしてくれます。HTTPリクエストのContent-Typeがapplication/jsonであれば、@RequestBodyが正しく動作します。
5. データクラス(DTO)を使った受け取りのやり方
Springでは、クライアントからのリクエストを受け取るとき、専用のデータクラスを用意しておくと便利です。これを「DTO(Data Transfer Object)」と呼びます。DTOを使うことで、データの構造を明確にし、メンテナンス性の高いコードが書けます。
DTOは単なるPOJO(Plain Old Java Object)で、フィールド・ゲッター・セッターだけを持ち、ビジネスロジックを持たないクラスです。
public class UserDto {
private String name;
private String email;
// ゲッター
public String getName() {
return name;
}
// セッター
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
そして、このDTOクラスをSpringのコントローラで利用します。
@Controller
public class UserController {
@PostMapping("/register")
@ResponseBody
public String registerUser(@RequestBody UserDto userDto) {
return "登録完了:" + userDto.getName() + "(" + userDto.getEmail() + ")";
}
}
このようにDTOを使うことで、JSON形式のリクエストをより整理された形で受け取ることができます。データ構造が変更されたときにも、DTOを修正するだけで済むため、拡張性にも優れています。
また、将来的にバリデーション機能(入力チェック)を追加したいときにも、DTOを使っておくと非常に便利です。@RequestBodyとDTOを組み合わせることで、SpringアプリケーションにおけるAPI設計がより効率的かつ安全になります。
6. よくあるエラーと原因(415エラー、400エラーなど)
Springで@RequestBodyを使ってJSONを受け取るときに、初心者が最もよく遭遇するのが「HTTPステータスコードによるエラー」です。ここでは、代表的なエラーである415エラーと400エラーの原因と対処法について説明します。
HTTPステータスコード415 Unsupported Media Type
このエラーは、クライアントが送信するリクエストのContent-Typeが不適切な場合に発生します。JSONを送るときは、必ずヘッダーにContent-Type: application/jsonを指定する必要があります。
HTTP 415 Unsupported Media Type
たとえば、JavaScriptのfetchでContent-Typeが設定されていないと、このエラーが出ることがあります。以下のように明示的に指定しましょう。
headers: {
"Content-Type": "application/json"
}
HTTPステータスコード400 Bad Request
このエラーは、クライアントから送られてきたJSONの構造が、サーバー側のJavaクラスと一致しないときに発生します。
HTTP 400 Bad Request
たとえば、JSONのキーがJavaのフィールド名と違う場合や、値の型が異なる場合などです。サーバーがデータを正しくパースできないため、400エラーが返されます。
7. よくある初心者のつまずき
初心者がSpringで@RequestBodyを使うときに、つまずきやすいポイントは意外とたくさんあります。ここでは、よくあるミスとその対処方法を紹介します。
Content-Typeの指定を忘れる
JavaScriptでリクエストを送るとき、Content-Typeヘッダーを省略すると、SpringはリクエストをJSONとして認識できません。これは、415エラーの原因にもなります。必ず以下のように指定しましょう。
fetch("/user", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({ name: "Taro", email: "taro@example.com" })
});
JSONのキーとJavaのフィールド名が一致していない
たとえば、JSONでは"userName"なのに、Javaのクラスではprivate String name;となっていると、マッピングに失敗してnullになるか、400エラーになります。
{
"userName": "Taro",
"email": "taro@example.com"
}
これを解決するには、JSONのキーをJavaのフィールド名に合わせるか、Jacksonの@JsonPropertyアノテーションを使う方法がありますが、本記事ではSpring標準の範囲内に限定するため、フィールド名をJSONに合わせる方法をおすすめします。
ゲッター・セッターの定義漏れ
Javaクラスのフィールドには、必ずgetXxx()とsetXxx()を定義しておく必要があります。これがないと、Springは値をセットできず、正しくマッピングされません。
8. @RequestBodyを使うときの注意点とポイント
@RequestBodyは非常に便利ですが、使い方を間違えるとエラーや意図しない挙動につながります。以下のポイントに注意することで、安定したSpringアプリケーションを構築できます。
1. リクエストメソッドはPOSTまたはPUTを使う
@RequestBodyはHTTPリクエストのボディに含まれるJSONを処理するため、GETメソッドでは通常使用しません。POSTメソッドかPUTメソッドで使うようにしましょう。
2. Content-Typeは常にapplication/jsonを指定
クライアントからのリクエストでは、必ずContent-Typeヘッダーをapplication/jsonに設定する必要があります。これがないとSpringがJSONとして解析できず、415エラーになります。
3. Javaクラスの構造とJSONの構造は一致させる
JSONのキーと、Javaのフィールド名が一致しているか、型が合っているかを事前に確認しておきましょう。これがずれていると、400エラーやnull値になる原因になります。
4. 引数は1つの@RequestBodyだけ
メソッドの引数に複数の@RequestBodyを使うことはできません。Springでは、1つのHTTPリクエストボディに対応できるのは1つのJavaオブジェクトだけです。
// これはエラーになります
@PostMapping("/sample")
@ResponseBody
public String sample(@RequestBody User user, @RequestBody Info info) {
return "NG";
}
5. JSONの配列を受け取る場合はListで
もし複数のデータを一括で受け取りたい場合は、JavaのListを使いましょう。次のように定義できます。
@PostMapping("/bulk")
@ResponseBody
public String receiveList(@RequestBody List<User> userList) {
return "件数:" + userList.size();
}
このようにして、Springの@RequestBodyは、単一のオブジェクトだけでなく、配列やリスト形式のJSONも受け取れるのです。