Spring MVCでJSONレスポンスを返す方法|@ResponseBodyの基本を初心者向けに解説
新人
「Spring MVCで画面じゃなくて、データだけを返すことってできるんですか?」
先輩
「できますよ。Spring MVCでは、JSONのようなデータをそのままレスポンスとして返す仕組みがあります。」
新人
「画面を返さないのに、Controllerを使うんですか?」
先輩
「はい。Controllerの役割を理解すると、画面とデータの違いがはっきり分かります。順番に整理していきましょう。」
1. Spring MVCにおけるレスポンスの基本的な考え方
Spring MVCでは、ブラウザや外部から送られてきたリクエストに対して、 コントローラがレスポンスを返します。 このレスポンスには大きく分けて二つの考え方があります。 一つはHTML画面を返す方法、もう一つはデータそのものを返す方法です。
初心者が最初につまずきやすいのは、 「Controllerは必ず画面を返すもの」という思い込みです。 実際には、Spring MVCのControllerは返す内容を柔軟に切り替えることができます。 そのため、Webアプリ開発だけでなく、JSONレスポンスを使ったデータ通信にも対応できます。
Pleiadesで作成したSpring MVCプロジェクトでも、 この基本的な考え方は変わりません。 GradleでビルドしたSpringプロジェクトにおいても、 Controllerはレスポンスの種類を意識して設計することが重要です。
2. 画面を返す場合とデータを返す場合の違い
Spring MVCで画面を返す場合、 Controllerのメソッドは画面名を文字列として返します。 これにより、HTMLファイルと結び付けられ、ブラウザに画面が表示されます。
一方で、データを返す場合は、 画面名ではなく、文字列やオブジェクトそのものをレスポンスとして返します。 この違いを理解していないと、 「画面が表示されない」「文字だけが表示される」 といった混乱が起きやすくなります。
まずは、画面を返すControllerの基本的な例を見てみましょう。 ここでは、Spring MVCでよく使われる画面遷移の形を示します。
package com.example.demo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class ViewController {
@GetMapping("/top")
public String top() {
return "top";
}
}
この場合、Controllerは「top」という画面名を返しています。 Spring MVCはこの戻り値を画面として解釈し、 対応するHTMLを表示します。 これが画面を返す場合の基本的な動きです。
3. JSONレスポンスとは何か
JSONレスポンスとは、 画面ではなく、データをJSON形式で返すレスポンスのことです。 JSONは、キーと値の組み合わせで構成されるデータ形式で、 Web開発では非常によく使われています。
Spring MVCでは、 Controllerから文字列やオブジェクトを返すことで、 JSON形式のレスポンスを作ることができます。 その際に重要な役割を持つのが@ResponseBodyです。
@ResponseBodyを使うことで、 Spring MVCは戻り値を画面名として扱わず、 そのままレスポンスデータとして返します。 これにより、ブラウザや外部システムにJSONレスポンスを送信できます。
package com.example.demo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class JsonSampleController {
@GetMapping("/api/hello")
@ResponseBody
public String hello() {
return "Hello JSON Response";
}
}
この例では、@Controllerを使いながら、 @ResponseBodyを付けることでデータを直接返しています。 ブラウザでアクセスすると、 HTML画面ではなく文字データが表示されます。 この動きが、JSONレスポンスの基本的な考え方です。
4. @ResponseBody の役割と基本的な使い方
Spring MVCでJSONレスポンスを返す際に中心となるのが@ResponseBodyです。 @ResponseBodyは、Controllerのメソッドが返した値を、 「画面名」ではなく「レスポンスデータ」として扱うための指定です。 これを付けるかどうかで、Spring MVCの動きは大きく変わります。
@ResponseBodyを付けない場合、 Controllerの戻り値は画面名として解釈されます。 一方で、@ResponseBodyを付けた場合は、 その戻り値がそのままHTTPレスポンスとして返されます。 この違いを理解することが、JSONレスポンス理解の第一歩です。
例えるなら、@ResponseBodyが無い場合は 「この名前の画面を探して表示する」動きになり、 @ResponseBodyがある場合は 「この中身をそのまま相手に渡す」動きになります。 Spring MVCでは、この切り替えを明示的に指定する必要があります。
@Controller
public class ResponseSampleController {
@GetMapping("/sample/text")
@ResponseBody
public String text() {
return "sample response";
}
}
この例では、文字列を返していますが、 Spring MVCはそれを画面名として扱わず、 レスポンス本文としてそのまま返します。 ブラウザでアクセスすると、 HTML画面ではなく文字だけが表示されます。
5. @Controller で JSON を返す仕組み
Spring MVCでは、@Controllerと@ResponseBodyを組み合わせることで、 JSON形式のレスポンスを返すことができます。 これは、Controllerが返したJavaオブジェクトを、 Spring MVCが自動的にJSONへ変換してくれる仕組みがあるためです。
初心者が疑問に思いやすいのは、 「自分でJSON文字列を書いていないのに、なぜJSONになるのか」 という点です。 実際には、Spring MVCの内部で変換処理が行われています。
まずは、単純なデータを返す例を見てみましょう。 Mapを返すと、キーと値の組み合わせがJSONとして表現されます。
package com.example.demo.controller;
import java.util.HashMap;
import java.util.Map;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class JsonMapController {
@GetMapping("/api/info")
@ResponseBody
public Map<String, String> info() {
Map<String, String> data = new HashMap<>();
data.put("language", "Java");
data.put("framework", "Spring MVC");
return data;
}
}
このように、Controllerの戻り値としてMapを返すだけで、 Spring MVCが自動的にJSON形式へ変換します。 開発者がJSON文字列を手作業で作る必要はありません。 これがSpring MVCの大きな便利ポイントです。
6. JavaオブジェクトがJSONに変換される流れ
Spring MVCでJavaオブジェクトがJSONに変換される流れは、 初心者にとって少し分かりにくい部分です。 しかし、全体の流れを押さえておくと理解しやすくなります。
まず、ControllerのメソッドがJavaオブジェクトを返します。 次に、@ResponseBodyが付いていることで、 Spring MVCは「これは画面ではなくデータだ」と判断します。 その後、内部の変換処理によってJSON形式に変換されます。
この変換処理は、Spring MVCが自動で行うため、 通常は開発者が意識する必要はありません。 ただし、仕組みを知っておくことで、 「なぜJSONが返ってくるのか」がはっきり理解できます。
package com.example.demo.model;
public class User {
private String name;
private int age;
public User(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
package com.example.demo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class UserController {
@GetMapping("/api/user")
@ResponseBody
public User user() {
return new User("Taro", 20);
}
}
この例では、ControllerがUserオブジェクトを返しています。 Spring MVCはこのオブジェクトを解析し、 フィールドの情報をもとにJSONレスポンスを生成します。 開発者はJavaのクラスを用意するだけで、 自然にJSONレスポンスを扱えるようになります。
まずはこの流れを理解することが、 Spring MVCでJSONレスポンスを扱う上での大きな土台になります。
7. JSONレスポンスが使われる具体的な場面
Spring MVCでJSONレスポンスを返す場面は、画面表示だけでは足りないときに多く登場します。 例えば、画面は表示しているものの、画面の一部だけを更新したいときがあります。 入力途中に候補を出したり、ボタンを押したら結果だけを再表示したりする場面では、 HTML全体を返すよりも、必要な情報だけをJSONで返した方が整理しやすくなります。
また、社内システムのようなWebアプリでも、別画面や別機能とデータをやり取りしたいことがあります。 Spring BootとSpring MVCのControllerを使ってJSONレスポンスを返せるようになると、 画面中心の開発をしながら、必要な場面だけデータ通信を混ぜることができます。 これは初心者にとっても大きな学習メリットになります。
ここでは、検索結果をJSONで返す例を紹介します。 例えば、キーワードを受け取り、候補の一覧を返すような処理です。 画面遷移をせずに情報だけ返す感覚をつかむと、Spring MVCの理解が進みます。
package com.example.demo.controller;
import java.util.ArrayList;
import java.util.List;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class SuggestController {
@GetMapping("/api/suggest")
@ResponseBody
public List<String> suggest(@RequestParam("keyword") String keyword) {
List<String> result = new ArrayList<>();
result.add(keyword + " 入門");
result.add(keyword + " 基本");
result.add(keyword + " 使い方");
return result;
}
}
このControllerは、keywordという入力を受け取り、候補の文字列リストを返します。 返しているのは画面名ではなくデータなので、@ResponseBodyが付いています。 Spring MVCでは、このような処理をControllerで用意するだけで、 JSONレスポンスとして扱えるのが特徴です。
8. 初心者が @ResponseBody でつまずきやすいポイント
@ResponseBodyで初心者がつまずきやすいポイントは、動きの違いが見た目で分かりにくい点です。 特に多いのが、戻り値の文字列を「画面名」だと思っているのに、 実際は「レスポンス本文」として返ってしまうケースです。 この状態になると、画面が表示されるはずなのに文字だけが表示され、 何が起きたのか分からなくなります。
例えるなら、宛先を書いた封筒を渡したつもりが、 宛先ではなく中身の紙だけを渡してしまったような状態です。 Spring MVCでは、@ResponseBodyがあると中身を直接渡す動きになるため、 画面名を返す設計とは考え方を切り替える必要があります。
次の例では、同じように文字列を返していますが、 @ResponseBodyがある場合と無い場合で意味が変わります。 初心者は、この違いを最初に整理しておくと混乱が減ります。
package com.example.demo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class ResponseBodyCompareController {
@GetMapping("/page/name")
public String pageName() {
return "top";
}
@GetMapping("/data/text")
@ResponseBody
public String dataText() {
return "top";
}
}
pageNameは画面名としてtopを返す設計です。 一方でdataTextは、topという文字列をデータとして返す設計です。 見た目はどちらも同じ文字列を返していますが、 Spring MVCにとっては全く別の意味になります。 ここを曖昧なままにすると、Controller設計で迷いやすくなります。
さらに初心者が困りやすいのが、JSONが返らない場合です。 例えば、返すオブジェクトに取得用のメソッドが無い場合や、 返したい情報がうまく組み立てられていない場合です。 そのため、まずはMapやListのような単純な戻り値から試し、 次にJavaクラスを返す流れに進むのがおすすめです。
9. 画面表示とJSONレスポンスの使い分け
Spring BootとSpring MVCで開発を進めるときは、 画面表示とJSONレスポンスを用途に応じて使い分けることが大切です。 画面表示は、利用者がブラウザで操作するための表示を作る目的があります。 JSONレスポンスは、データだけをやり取りし、必要な部分だけ更新したい目的があります。
初心者が理解しやすい判断基準は、 「画面遷移が必要かどうか」です。 画面遷移が必要なら画面名を返すControllerを作り、 画面遷移が不要で情報だけ渡したいなら@ResponseBodyでデータを返します。 この基準を持つと、Controllerの役割を整理しやすくなります。
次の例では、同じControllerクラスの中に 画面表示用の処理とJSONレスポンス用の処理を置いています。 現場では役割で分けることもありますが、 初心者はまず一つの流れとして理解すると覚えやすくなります。
package com.example.demo.controller;
import java.util.HashMap;
import java.util.Map;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class MixedController {
@GetMapping("/dashboard")
public String dashboard() {
return "dashboard";
}
@GetMapping("/api/dashboard/summary")
@ResponseBody
public Map<String, Object> summary() {
Map<String, Object> result = new HashMap<>();
result.put("status", "ok");
result.put("count", 3);
return result;
}
}
dashboardは画面表示のためのControllerです。 summaryはJSONレスポンスのためのControllerです。 URLの設計を分けておくと、どちらが画面でどちらがデータかが分かりやすくなります。 Spring MVCでは、Controllerが返すものを明確にすることが、 保守しやすい開発につながります。
10. 初心者はまず何を理解すべきか
Spring MVCでJSONレスポンスを返す方法を学ぶときに、 初心者が最初に理解すべきことは、 Controllerの戻り値が何を意味しているのかを区別することです。 画面名として扱われるのか、レスポンス本文として扱われるのかを理解できると、 Spring MVCの動きが読みやすくなります。
次に重要なのが、@ResponseBodyの役割です。 これがあることで、画面表示の設計からデータ通信の設計へ切り替えられます。 まずは文字列やMapやListでJSONレスポンスを返す練習をして、 その後にJavaオブジェクトを返す流れへ進むと理解しやすくなります。
さらに学習を進めるなら、 パラメータの受け取り方や返却データの設計を学ぶと良いです。 例えば、入力値を受け取って結果をJSONで返す流れを作れるようになると、 Spring BootとSpring MVCのController設計が実務に近づいていきます。
Pleiades環境でSpringプロジェクトを作り、 Gradleでビルドして動かしながら、 画面表示とJSONレスポンスの違いを体験することが、 最も理解が深まる学び方です。 Spring MVCの基本として@ResponseBodyを押さえると、 Web開発の幅が広がり、次に学ぶ内容も見えやすくなります。