@Controllerと@RestControllerの違いと正しい使い分け方|Spring MVC入門
生徒
「Springで@Controllerと@RestControllerって見かけますけど、違いがよく分かりません……」
先生
「それぞれ役割が少し違うんです。Web画面を返すか、JSONやXMLなどのデータを返すかによって使い分けます。」
生徒
「なるほど……!じゃあ、どうやって使い分ければいいんですか?」
先生
「実際にコードを見ながら、初心者でも理解できるように詳しく説明していきましょう!」
1. @Controllerと@RestControllerの基本的な違い
Spring MVCにおける@Controllerと@RestControllerは、どちらもクライアントからのリクエストに応答するためのクラスに付けるアノテーションです。
- @Controller:HTMLテンプレート(Thymeleafなど)を返す場合に使います。
- @RestController:JSONやXMLなどのデータを返すREST API用に使います。
つまり、Web画面を表示したい場合は@Controller、データ通信(API)を行いたい場合は@RestControllerを使います。
2. @Controllerの使い方(HTMLを返す)
@Controllerは、Spring BootでThymeleafなどのテンプレートエンジンを使ってHTMLを表示する際に利用されます。次のような書き方になります:
package com.example.demo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class WebController {
@GetMapping("/hello")
public String hello(Model model) {
model.addAttribute("name", "山田太郎");
return "hello";
}
}
このように書くと、src/main/resources/templates/hello.htmlというテンプレートファイルが読み込まれます。ビュー(画面)を返すのが特徴です。
3. @RestControllerの使い方(JSONを返す)
@RestControllerは、@Controllerと@ResponseBodyを組み合わせたアノテーションです。返り値はJSON形式になります。
package com.example.demo.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
@RestController
public class ApiController {
@GetMapping("/api/hello")
public Map<String, String> helloApi() {
return Map.of("message", "こんにちは、REST APIの世界へ!");
}
}
このコードでは、/api/helloにアクセスすると、以下のようなJSONレスポンスが返されます。
{"message":"こんにちは、REST APIの世界へ!"}
4. @ResponseBodyの役割と@RestControllerとの関係
@Controllerに@ResponseBodyをつけると、JSONなどのデータが直接レスポンスとして返されます。つまり、以下の2つは同じ意味になります:
@RestController
public class SampleApi {}
@Controller
@ResponseBody
public class SampleApi {}
ただし、実際には@RestControllerを使った方がコードがスッキリし、初心者にも読みやすくなります。
5. @Controllerと@RestControllerの使い分けパターン
Webアプリケーションの中で、画面を表示する部分とデータをやり取りするAPI部分が分かれている場合、それぞれを適切に使い分けることが重要です。
- 画面の表示:ユーザー向けのHTMLを返す →
@Controller - データ通信:JavaScriptや他のシステムとのデータ交換 →
@RestController
例えば、管理画面などでフォーム送信後にページ遷移したいなら@Controllerを、VueやReactなどのフロントエンドと連携するなら@RestControllerを使います。
6. @Controllerと@RestControllerの混在は可能か?
もちろん可能です。同じSpring Bootプロジェクト内に、@Controllerを使ったHTML表示用のクラスと、@RestControllerを使ったAPI用のクラスを共存させることができます。
よくある構成は以下の通りです:
com.example.demo
├── controller
│ ├── WebController.java // @Controller(HTML)
│ └── ApiController.java // @RestController(JSON)
このように役割を分離することで、コードの見通しも良くなり、保守性も高まります。
7. HTMLテンプレート例(Thymeleaf)
@Controllerで使用するThymeleafテンプレートの例を紹介します:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>こんにちは</title>
</head>
<body>
<h1 th:text="'ようこそ、' + ${name} + 'さん!'">ようこそ!</h1>
</body>
</html>
8. よくあるエラーとその原因
初心者がつまずきやすいポイントとして、以下のようなエラーがあります:
- Whitelabel Error Page:テンプレートファイルの名前や場所が間違っていないか確認しましょう。
- JSONが返ってこない:
@RestControllerを使わずに@Controllerだけで書いている場合、@ResponseBodyを追加する必要があります。 - 404 Not Found:URLパスや
@GetMappingの指定ミスに注意しましょう。
まとめ
Spring MVCにおける@Controllerと@RestControllerの違いと使い分け方をしっかりと理解しておくことは、Webアプリケーションの設計や実装において非常に重要です。この記事では、それぞれのアノテーションの役割や用途、具体的な使用例、そして初心者がつまずきやすいエラーのポイントまで丁寧に解説しました。
@Controllerは主にHTMLの画面表示を行う際に使用し、Thymeleafなどのテンプレートエンジンと組み合わせてユーザーにわかりやすいインターフェースを提供します。一方、@RestControllerはJSON形式のレスポンスを提供するREST APIを構築するためのもので、Ajax通信やフロントエンドフレームワークとの連携で活躍します。
また、@RestControllerは@Controllerに@ResponseBodyを追加した構成であるため、裏側の動きも理解しておくとより柔軟に使いこなせるようになります。Spring Bootではこれらのアノテーションを組み合わせることで、フロントエンドとバックエンドを同一プロジェクト内で効率的に構築できるのが大きな利点です。
実際の現場では、API開発と画面開発を同時に進めることも多いため、@Controllerと@RestControllerを適切に使い分ける技術力は重宝されます。MVCモデルの基本であるController層の理解を深めることで、将来的に認証・認可・エラーハンドリングなどの応用技術にもスムーズに移行できます。
最後に、よくあるエラーの対処法を覚えておくことで、開発中のトラブルを未然に防ぐことができます。初学者のうちは設定ミスやマッピングの指定忘れなどでつまずきがちですが、ひとつひとつ原因を整理しながら学習していけば必ず成長につながります。
確認用サンプル:@Controllerと@RestControllerを同時に使った構成
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
package com.example.demo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class HelloPageController {
@GetMapping("/page")
public String helloPage(Model model) {
model.addAttribute("name", "スプリング初心者");
return "hello";
}
}
package com.example.demo.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
@RestController
public class HelloApiController {
@GetMapping("/api/greeting")
public Map<String, String> greet() {
return Map.of("greeting", "こんにちは!JSONで返しています。");
}
}
生徒
「@Controllerと@RestControllerの違い、かなりクリアになってきました!」
先生
「それは良かったです。画面を返したいときは@Controller、データだけを返したいときは@RestControllerを使うんでしたね。」
生徒
「はい。特にThymeleafで画面を作る部分と、JavaScriptからの非同期通信でJSONを受け取る部分を、役割ごとにControllerを分けておくと管理しやすいと感じました。」
先生
「その通りです。プロジェクトが大きくなるほど、Controllerの整理はとても大切になりますから、今のうちから意識して設計できるようにしていきましょう。」
生徒
「今度は@PostMappingや@PutMappingも学んで、フォーム処理や更新処理もできるようになりたいです!」
先生
「良い意欲ですね。それでは次はフォーム送信やREST APIの更新処理について学んでいきましょう!」