Skip to main content

コントローラとルーティング

Webアプリケーションでは、 ブラウザからのリクエストをどの処理に結びつけるか が最も基本的な仕組みである。 この章では、Spring MVCの「コントローラ」と「ルーティング」について学ぶ。 URLの指定に応じてJavaの処理を呼び出し、結果としてHTMLを返すまでの一連の流れを理解する。

学習のゴール

  • ルーティングの役割を理解し、URLと処理を結びつけられる
  • GETとPOSTの違いを説明できる
  • @Controller アノテーションの役割を説明し、コントローラクラスを作成できる
  • @GetMapping / @PostMapping を使い、特定のURLに対応するメソッドを定義できる
  • @GetMapping@PostMapping の使い分けができる
  • @RequestMapping の使い方がわかる
  • メソッドから return でビュー名を返せる
  • URLからどのメソッドが実行されるか判断できる
  • コントローラが検出されない原因を推測できる
  • ビューファイルの配置場所のルールを理解し、正しい構成で実装できる
  • リダイレクトの仕組みを理解し、redirect: プレフィックスを使って実装できる

ルーティングとは

ルーティングとは、 ブラウザから送られてきたURLから「どの処理を呼び出すか」を読み取る仕組み である。

例:http://localhost:8080/welcome

http://localhost:8080/welcome
| | |
| | └─ パス(アプリ側で処理を振り分ける対象)
| └─ ポート番号
└─ ホスト名

この場合、ルーティングで指定する文字列は /welcome にあたる。 Spring MVCでは、この「パス」とプログラム(処理)を結びつけるために コントローラ を利用する。

HTTPメソッド(GET と POST)

URLのパスに加えて、ブラウザは HTTPメソッド と呼ばれる「リクエストの種類」も送信する。

HTTPメソッド主な用途
GETデータの取得・ページの表示URLを直接開く、リンクをクリックする
POSTデータの送信・登録・更新フォームの送信ボタンを押す

Spring MVCでは、同じURLでもGETとPOSTを別のメソッドで処理できる。 これが @GetMapping@PostMapping の使い分けの根拠である。


コントローラの基本

Spring MVCにおける「コントローラ」とは、 ルーティングで読み取ったURLパスに対応する処理を実行し、結果としてビューを返す役割 を持つクラスである。

  • @Controller アノテーションを付けたクラスは、リクエストを処理する役割を持つ
  • クラス自体は自分で new しない。Springが自動的にインスタンス化して管理する(詳細はDIの章で解説)
  • Spring Bootでは、 @SpringBootApplication が置かれているパッケージ またはそのサブパッケージ にコントローラを置く必要がある
com.example.demo ← ここに@SpringBootApplicationが置かれている
├ DemoApplication.java
└ controller/ ← コントローラはこのサブパッケージに置く
└ HelloController.java
コントローラが 404 になる場合

コントローラを正しく実装しても、 置くパッケージが間違っている と Springが検出できずリクエストは 404 になる。

よくある原因:

  • com.example.demo の下ではなく、全く別のパッケージ(例:com.controller)に置いてしまっている
  • DemoApplication.java と同じパッケージか、そのサブパッケージになっているか確認する

高度な設定で @ComponentScan を使えばスキャン範囲を変更できるが、今回は扱わない。


@GetMapping と @PostMapping

リクエストを処理するメソッドを決めるために、Spring MVCではアノテーションを使う。

@GetMapping — GETリクエストを処理する

ブラウザでURLを直接開いたとき(GETリクエスト)の処理を定義する。

SampleController.javajava
@Controller
public class SampleController {
@GetMapping("/welcome")
public String welcome() {
return "greet"; // → templates/greet.html を返す
}
}
  • @GetMapping("/welcome")/welcome へのGETリクエストをこのメソッドで処理する
  • return "greet"templates/greet.html を表示する(ビューの解決)

@PostMapping — POSTリクエストを処理する

フォームの送信ボタンを押したとき(POSTリクエスト)の処理を定義する。

SampleController.javajava
@Controller
public class SampleController {
@GetMapping("/contact")
public String contactForm() {
return "contact"; // フォームページを表示
}
@PostMapping("/contact")
public String contactSubmit() {
// フォームデータを処理する
return "redirect:/thanks"; // 処理後にリダイレクト
}
}

同じURL /contact でも、GETとPOSTで異なるメソッドが呼び出される点に注目する。

@RequestMapping との関係

@GetMapping@PostMapping は、より汎用的な @RequestMapping の省略形である。

// @RequestMapping を使った書き方(冗長)
@RequestMapping(value = "/welcome", method = RequestMethod.GET)
public String welcome() { ... }

// @GetMapping を使った書き方(推奨)
@GetMapping("/welcome")
public String welcome() { ... }
アノテーション対応するHTTPメソッド使い分け
@RequestMappingすべて(GET / POST / PUT / DELETE など)複数メソッドを1つで処理したい場合
@GetMappingGET のみページ表示・データ取得に使う(推奨)
@PostMappingPOST のみフォーム送信・データ登録に使う(推奨)

実務では @GetMapping / @PostMapping を使う方が意図が明確になるため推奨される。


ビューの置き場所

Spring Bootでは、ビューとして返すHTMLファイルは 必ず 以下の場所に配置する。

src/
└ main/
├ java/ … Javaコード
└ resources/
└ templates/ … Thymeleaf の HTMLファイル
├ greet.html
└ other.html

コントローラから return "greet"; と書くと、 Springは src/main/resources/templates/greet.html を探す。

templates 以下にディレクトリを作ることも可能である。 その場合、コントローラからはスラッシュ区切りで指定する。

UserController.javajava
@Controller
public class UserController {
@GetMapping("/user")
public String userDetail() {
return "user/detail"; // → templates/user/detail.html を返す
}
}
TemplateInputException(テンプレートが見つからないエラー)

return "greet" に対して templates/greet.html が存在しない場合、 TemplateInputException: Error resolving template [greet] というエラーが発生する。

チェックポイント:

  1. ファイルが src/main/resources/templates/ 配下に置かれているか
  2. return の文字列とファイル名(拡張子なし)が一致しているか
  3. ディレクトリ構成を使う場合、return "user/detail" のように正確に指定しているか

リダイレクト

コントローラのメソッドから 別のURLへリダイレクト させることができる。 フォーム送信後に別ページへ移動させる場合などに使う。

return の値を "redirect:/パス" の形式にするだけでよい。

SampleController.javajava
@Controller
public class SampleController {
@PostMapping("/register")
public String register() {
// 登録処理...
return "redirect:/complete"; // /complete へリダイレクト
}
}
  • redirect:/complete … ブラウザに /complete への再リクエストを促す
  • リダイレクト後は新しいGETリクエストとして処理されるため、フォームの二重送信を防げる
いつ redirect: を使うか

POST送信の後 は、原則としてリダイレクトを使う( PRGパターン )。

理由:ページをリロードすると同じPOSTリクエストが再送信されてしまうため、 リダイレクトによって最後のリクエストをGETに変えることで二重送信を防ぐ。

  • フォーム送信 → 登録処理 → redirect:/complete(推奨)
  • フォーム送信 → 登録処理 → return "complete" → リロード時に再送信される(非推奨)

よくある質問

Q. @GetMapping@RequestMapping はどちらを使えばよいですか?

A. 基本的には @GetMapping / @PostMapping を使う方が推奨される。 メソッド名にHTTPメソッドの種類が含まれるため、コードを読んだときに意図がわかりやすくなる。 @RequestMapping は複数のHTTPメソッドを1つで扱いたい特別な場合に使う。


Q. コントローラのメソッド名は決まっていますか?(例:welcome でないとダメ?)

A. メソッド名は任意である。 welcome でも showTop でも displayPage でも動作する。 URLとの対応はアノテーション(@GetMapping のパス)で決まるため、メソッド名は自由につけてよい。 ただし、処理内容を表す意味のある名前をつけることが望ましい。


Q. コントローラを作ったのに 404 になります。なぜですか?

A. 主な原因は以下の3つである:

  1. パッケージの配置が間違っている@SpringBootApplication のパッケージまたはそのサブパッケージに置く必要がある
  2. @Controller アノテーションを忘れている — アノテーションがないとSpringに認識されない
  3. @GetMapping / @PostMapping のパス指定が間違っている — アクセスしているURLとパスが一致しているか確認する

Q. ビューファイルが見つからないエラー(TemplateInputException)の対処法は?

A. 以下を順番に確認する:

  1. src/main/resources/templates/ 配下にHTMLファイルが存在するか
  2. return で指定した文字列とHTMLファイル名(.html を除いた部分)が一致しているか
  3. サブディレクトリを使う場合、return "user/detail" のようにスラッシュ区切りで指定しているか

本章のまとめ

  • ルーティングとは、URLのパス部分と処理を結びつける仕組みである
  • GETはページ表示・データ取得、POSTはフォーム送信・データ登録に使う
  • @Controller を付けたクラスはSpringにより自動でインスタンス化される(自分で new はしない)
  • コントローラは @SpringBootApplication のパッケージまたはそのサブパッケージに置く必要がある
  • @GetMapping / @PostMapping でURLと処理を紐づける(@RequestMapping の省略形)
  • ビューは src/main/resources/templates/ 配下に配置し、 return の文字列(拡張子なし)で指定する
  • return "redirect:/パス" でリダイレクトができ、POST後のリダイレクトはフォーム二重送信を防ぐ

次章では、ブラウザから送られてくるリクエストパラメータをコントローラで受け取る方法を学ぶ。


Webアプリケーションにおける「ルーティング」の説明として、最も適切なものを選べ。

正解

C. URLのパスと、そのリクエストを処理するメソッドを対応付ける仕組みのこと

解説

ルーティングとは、受信したHTTPリクエストのURLパスに対して、どのコントローラのどのメソッドで処理するかを対応付ける仕組みである。

Springでは @GetMapping@PostMapping などのアノテーションを使って、URLとメソッドを紐付けるルーティングを設定する。

例:

  • @GetMapping("/products") → 商品一覧表示メソッド
  • @PostMapping("/products") → 商品登録処理メソッド

SpringにおけるGETとPOSTの使い分けとして、最も適切なものを選べ。

正解

A. GETはページの表示・検索など情報取得に使い、POSTはフォーム送信など情報の登録・更新に使うのが一般的である

解説

GETリクエストは主にリソースの取得(ページ表示や検索)に使い、パラメータはURLに付加される。

POSTリクエストは主にデータの送信(フォーム送信や登録処理)に使い、データはリクエストボディに格納される。

同じURLでもGETとPOSTで異なる処理を割り当てることができる。

例:

  • GET /items → 一覧表示
  • POST /items → 新規登録

SpringMVCにおける @Controller アノテーションの役割として、最も適切なものを選べ。

正解

D. クラスがSpringMVCのコントローラであることを示し、HTTPリクエストを処理するメソッドを定義できるようにする

解説

@Controller アノテーションはSpringにそのクラスがMVCのコントローラであることを知らせる。

Springはアプリ起動時に @Controller が付いたクラスを自動検出し、@GetMapping などのアノテーションで定義されたURLマッピングを有効にする。

各アノテーションの役割:

  • @Controller: Webリクエストを処理するコントローラ
  • @Service: ビジネスロジックを担当するサービス
  • @Repository: データアクセスを担当するリポジトリ
  • @Component: 汎用的なSpringコンポーネント

ショップ機能を担当するコントローラクラスを作成せよ。

public class ShopController { }

解答例
@Controller public class ShopController { }
解説

@Controller アノテーションをクラスに付けることで、SpringMVCのコントローラとして機能する。

Springはコンポーネントスキャンによりこのアノテーションを持つクラスを自動検出し、Beanとして登録する。

クラス名は慣例として 〇〇Controller という名前にすることが多い。

/items へのGETリクエストを処理するメソッドを完成させよ。

public String itemList() { return "items/list"; }

解答例
@GetMapping("/items") public String itemList() { return "items/list"; }
解説

@GetMapping("/items")/items へのGETリクエストをこのメソッドに対応付ける。

メソッドの引数にはリクエストパラメータやモデルなどを受け取ることができる。

返り値の文字列はビュー名として扱われ、templates/items/list.html が描画される。

/items にアクセスしたとき、templates/items/list.html を表示するようにメソッドを完成させよ。

@GetMapping("/items") public String itemList() { return
; }

解答例
return "items/list";
解説

@Controller のメソッドが返す文字列はビュー名として解釈される。

Springは src/main/resources/templates/ 配下の対応するHTMLファイルをThymeleafで描画してレスポンスを返す。

  • return "items/list"templates/items/list.html を描画
  • return "redirect:/items"/items にリダイレクト

フォームからのPOSTリクエストを受け取り、処理後にリダイレクトするメソッドを完成させよ。

public String createItem() { // 登録処理 return "redirect:/items"; }

解答例
@PostMapping("/items") public String createItem() { return "redirect:/items"; }
解説

@PostMapping はPOSTリクエストを処理するメソッドに付けるアノテーションである。

フォームのaction属性と一致するURLに @PostMapping を設定する。

処理後は通常 "redirect:/xxx" で別ページにリダイレクトする(PRGパターン:Post/Redirect/Get)。 これによりブラウザの再読み込みで二重送信を防ぐことができる。

SpringMVCにおける @GetMapping@PostMapping の適切な使い分けとして、正しいものを選べ。

正解

B. データ表示・検索には`@GetMapping`、フォーム送信・データ登録・更新・削除には`@PostMapping`を使う

解説

同じURL(例:/items)に対して @GetMapping(一覧表示)と @PostMapping(新規登録)の両方を設定することができる。

一般的な使い分け:

  • @GetMapping: データ取得・ページ表示(べき等な操作)
  • @PostMapping: フォーム送信・データの作成・更新・削除(べき等でない操作)

例:

@GetMapping("/items")   // 一覧表示
@PostMapping("/items")  // 新規登録

以下のコントローラで、ブラウザからGETリクエストで /products にアクセスしたとき、実行されるメソッドとして正しいものを選べ。

@Controller
public class ProductController {
@GetMapping("/products")
public String list() {
return "products/list";
}

@GetMapping("/products/{id}")
public String detail() {
return "products/detail";
}

@PostMapping("/products")
public String create() {
return "redirect:/products";
}
}

正解

A. GETで`/products`にアクセスすると`list()`が実行される

解説

@GetMapping("/products") はGETメソッドかつ /products というURLへのリクエストを list() メソッドに対応付ける。

  • 同じ /products でもPOSTリクエストは create() が実行される
  • /products/1 のようなパスパラメータ付きのURLには @GetMapping("/products/{id}")detail() が対応する

HTTPメソッド(GET/POST)とURLの組み合わせで、実行されるメソッドが決まる。

以下のSpring Bootアプリで /hello にアクセスしても404エラーになる。原因として最も適切なものを選べ。

// メインクラス(パッケージ: com.example.demo)
package com.example.demo;

@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}

// コントローラ(パッケージ: com.other.controller)
package com.other.controller;

@Controller
public class HelloController {
@GetMapping("/hello")
public String hello() {
return "hello";
}
}

正解

C. コントローラのパッケージがメインクラスのパッケージ配下にないため、コンポーネントスキャンに含まれないから

解説

@SpringBootApplication が付いたクラスのパッケージと、そのサブパッケージにあるクラスだけがコンポーネントスキャンの対象となる。

例:

  • メインクラスのパッケージ: com.example.demo
  • スキャン対象: com.example.demo.*(サブパッケージすべて)
  • スキャン対象外: com.other.controller(別のルートパッケージ)

コントローラはメインクラスと同じパッケージか、そのサブパッケージに配置する必要がある。

@RequestMapping アノテーションの使い方として、正しいものを選べ。

正解

B. `@RequestMapping`はクラスに付けて共通のURLプレフィックスを指定したり、method属性でHTTPメソッドを指定したりできる

解説

@RequestMapping はメソッドとHTTPメソッドを指定できる汎用的なマッピングアノテーションである。

クラスへの使用例(共通プレフィックス)

@Controller
@RequestMapping("/products")
public class ProductController {
    @GetMapping("/list")    // → /products/list
    @GetMapping("/{id}")    // → /products/{id}
}

@GetMapping@RequestMapping(method = RequestMethod.GET) の省略形である。