前回はMVCモデルについて概略を学びました。
今回は本研修でコントローラーの役目を果たすSpring BootのControllerについて学んでいきましょう
1. Controllerとは?
Spring BootのController
Spring BootのControllerとは、ユーザからのリクエストを受け取り、必要に応じてビジネスロジック(Model)を呼び出し、結果をView(Thymeleafなど)に返すクラスのことです。
Spring Bootでは@Controller
や@RestController
アノテーションを付けたクラスがその役割を担います。
下図のようにブラウザからアプリケーション(Spring Boot)がリクエストを受けると、該当のControllerメソッドが呼ばれ、必要に応じてModelを操作してデータを取得・加工します。
そして、そのデータをThymeleafテンプレートに渡してHTMLを生成し、ブラウザへ返します。
1.1. ControllerでHello World
まずは、Spring Bootでの「Hello World」をやってみましょう。
以下のようなControllerクラス(例:Hello1Controller.java
)を作成します。
あらかじめSpring Bootプロジェクトを作成しておいてください(前章参照)。
package com.example.demo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class Hello1Controller {
@GetMapping("/hello1")
public String helloWorld() {
System.out.println("Hello World");
return "blank";
// blank.html(Thymeleafファイル)を表示する想定
}
}
@Controller
アノテーションによって、このクラスはHTTPリクエストを処理するControllerであるとSpringに認識されます。@GetMapping("/hello1")
は、http://localhost:8080/hello1
にGETリクエストが来たときに呼び出されるメソッドです。System.out.println("Hello World");
はログをコンソールに出力しています。ブラウザには表示されません。
実行してブラウザで/hello1
にアクセスすると、Thymeleafテンプレートblank.html
が返ってきます(中身が空なら真っ白なページ)。「Hello World」はEclipseなどの**コンソール(ログ)**に出力されているはずです。
どこに「Hello World」が表示された?
Eclipse(STS)では、コンソールビューがあり、System.out.printlnなどのログはそちらに表示されます。プリントデバッグや各種エラー出力を行う場所として頻繁に目にすることになります。
1.2. Request Mapping
Spring Bootでは@GetMapping("/hello1")
や@RequestMapping("/hello1")
を使います。
これは「このControllerメソッドは /hello1
というURLパスで呼び出せます」という意味です。
複数のControllerが同じURLパスを持っていると競合してしまい、正常に動作しない可能性があります。同じURLパスは一意にしておくのが基本ルールです。
実験
- 同じ
@GetMapping("/hello1")
を持つメソッドが複数存在すると競合を起こす可能性が高いので試してみて下さい。 - Spring Bootの場合、アプリ起動時にエラー(
Ambiguous mapping
など)が出ることも多いので注意します。
2. コンテキストルート
Spring Bootでは、デフォルトのコンテキストルートは「/
」(ルートパス)となっています。
3. Controllerクラス
@Controller
アノテーション付きクラスと、メソッドに@GetMapping
や@PostMapping
を付けることでHTTPのGET/POSTを受け取ることができます。
3.1. @GetMappingメソッド
GETリクエストを処理したい場合は、@GetMapping
を付けたメソッドを用意します。
@GetMapping("/hello2")
public String hello2() {
// GETリクエストを受け取った際の処理
return "viewname";
}
もしPOSTリクエストを処理したい場合は、@PostMapping
を付けたメソッドを用意します。
例題:
@PostMapping("/hello2")
のみを持つControllerメソッドしか用意しなかった場合に、ブラウザで/hello2
にアクセスしたらどうなるでしょうか?
→ ブラウザの通常アクセスはGETリクエストなので、404 (Not Found) になることが多いです。
3.2. Model(リクエスト属性)とは?
Spring Boot(Thymeleaf)でコントローラからViewへデータを渡すには、Modelという仕組みを使います。
@GetMapping("/hello2")
public String hello2(org.springframework.ui.Model model) {
model.addAttribute("message", "Hello World");
return "result"; // result.htmlへ渡す
}
model.addAttribute("message", "Hello World");
- 「message」という名前で
"Hello World"
をテンプレートに渡す。
- 「message」という名前で
return "result";
で指定したテンプレート(result.html
)からmessage
を参照できます。
スコープ(有効範囲)
model.addAttribute()
でセットしたデータは、そのリクエストでViewを表示するタイミングまで有効です。レスポンスが返却された後は破棄されるため、「使い捨て」の領域と考えられます。
3.3. 画面(Thymeleaf)にデータを渡す方法
Controllerメソッドの戻り値をThymeleafテンプレート名にすると画面にデータを渡すことができます。
Spring MVCでは、戻り値の文字列をView名として解釈し、テンプレートを表示します。
@GetMapping("/hello2")
public String hello2(Model model) {
model.addAttribute("message", "Hello World");
return "result"; // "result.html"が表示される
}
- forwardやredirectを使いたい場合は、
"forward:/xxx"
や"redirect:/xxx"
のように返却します。(詳しくは後の章で解説)
URLは http://localhost:8080/hello2
のままですが、実際にはresult.html
というテンプレートを使ってHTMLを生成し、ブラウザに返しています。
4. ThymeleafにおけるELの記述方法
EL (Expression Language) の書き方
Thymeleafでは、以下のように${変数名}
を書くと、Modelに設定された属性を取り出すことができます。
<p th:text="${message}"></p>
これにより、Controllerで model.addAttribute("message","Hello World")
とセットした値がHTMLに表示されます。
例: result.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Result</title>
</head>
<body>
<h1>結果表示</h1>
<p th:text="${message}">ここにメッセージが入ります</p>
</body>
</html>
Spring Bootでは「Controller」→「Thymeleafテンプレートに戻り値」としてデータを渡すのが基本のデータの流れです。
単体でHTMLを開いても、message
などは埋め込まれず、空の画面になります。(必ずControllerを経由して値をセットしてあげる必要があります。)
常にControllerを経由してThymeleafにアクセスさせる
直接Thymeleafテンプレート(.html)にアクセスするのは推奨されません。
理由は以下のようにほとんど同じです。
- ビジネスロジックが露出してしまう
- コントローラーを通さず直接テンプレートにアクセスされると、意図しないデータを表示・操作される可能性があります。
- URL設計の問題
- どのControllerから遷移したのか分からないため、パラメータの受け渡しや制御が難しくなります。
- セキュリティの問題
- 認証・認可をバイパスして直接ページにアクセスされる恐れがあります。
必ずControllerを経由し、Controller側でModelに値を設定し、正しいView名を返すようにしてください。
<まとめ:隣の人に正しく説明できたらチェックを付けましょう>
- Spring BootのControllerとは、Javaで書かれたサーバサイドプログラムである。
- Controllerはアプリケーションのメモリ上に常駐し、リクエストを受け取り、レスポンスを返す(細かいビジネスロジックはModelに任せる)。
- HTTPメソッドに応じて
@GetMapping
や@PostMapping
でメソッドを切り替えられる。 - コンソールでプリントデバッグでき、各種エラーも表示される。
@GetMapping("/hello")
などでURLパスとメソッドの対応を定義する(重複は避ける)。- Spring BootアプリケーションのURLは
http://ドメイン名:ポート番号/パス
となる(コンテキストパスを変更する場合はapplication.propertiesで設定可能)。 - ControllerからThymeleafに値を渡すにはModelを使用し、
model.addAttribute("name", value)
のように書く。 - HTMLテンプレート(View)を返すには、メソッドの戻り値にView名(例えば
"result"
)を返す。 - ThymeleafのELは
${変数名}
と書き、Modelに追加されたデータを参照する。
今回はControllerからThymeleafにデータを渡してWebに表示する流れについて学びました
IT企業向け新人研修おすすめ資料 無料公開中 (saycon.co.jp)