当社の新人エンジニア研修のWebアプリケーションとMVCパターン
当社の新人エンジニア研修のWebアプリケーションでは、MVCパターンを理解することを当面のゴールとしています。なぜなら、皆さんが実務につくと使用するであろう各種フレームワークがMVCパターンを考慮して作られているからです。
フレームワークの例としては、JavaのSpring Framework、C#のASP.NET Core MVC、PythonのDjango、Ruby on Railsなどが有名です。
この章では、MVCパターンの概略を紹介して、この後の章のガイド的な役割を果たします。
1. MVCパターンとは?
WebアプリケーションにおけるMVCパターンとは、主に以下の3つの要素から構成されるパターンです。
- Model:アプリケーションのビジネスロジックやデータを表す部分(通常のJavaクラスで実装)
- View:入出力(ユーザー画面)を担当する部分(Spring BootではThymeleafなどのテンプレートエンジンを使ったHTMLファイル)
- Controller:ユーザーからのリクエストを受け取り、処理(Model)に振り分けて、処理結果をViewに返す部分(Spring Bootでは
@Controller
アノテーションを付けたクラスで構成)
これらの頭文字を並べてMVCパターンと呼ばれています。MVCパターンはデザインパターンの一種で、過去のエンジニアが解決してきた設計のベストプラクティスがまとめられています。あとでDAO【Data Access Object】パターンなども学ぶ予定です。
データの流れ
①ブラウザからのリクエストが、Spring Bootアプリケーション内のControllerクラスに送られます。
②ControllerはメソッドでModelのインスタンスを生成し、ビジネスロジックを実行したり、データベースアクセスを行ったりして処理を依頼します。
③Controllerは処理結果のデータをViewに渡します。
④ViewがControllerから渡されたデータを利用してHTMLをレンダリング(画面に表示できるように)し、最終的にブラウザへレスポンスとして返します。
MVCパターンの概念を図示すると、以下のようになります。(イメージ図)

2. なぜMVCパターンなのか?
MVCパターンが考案された理由を一言で説明すると、画面とロジックを別々に開発するためです。
皆さんが目にするWebアプリケーションは、画面(UI)がとてもオシャレで洗練されていると思います。それもそのはず、それらの画面はプロのデザイナーが作っているからです。
一方、そのWebアプリケーションの機能を支えるロジック(プログラム)はプロのITエンジニアが作っています。
デザインと機能、この両方を一人の人間が担当するのは困難です。また、画面(View)と処理(ModelとController)を分けることで、不具合発生時に原因を特定しやすくなり、システムの更新もしやすくなるのです。
そのような理由から、Webアプリケーションの主流はMVCパターンになっているわけです。
3. MVCパターンの簡単な例
ここからは、最も単純な例を使ってMVCパターンを紹介しましょう。
以下は、Spring Bootプロジェクトにおけるサンプル構成例です(講師の指示に従ってMVCの役割を埋めてみましょう):
my-mvc-sample (プロジェクト名)
┣ src
┃ ┣ main
┃ ┃ ┣ java
┃ ┃ ┃ ┣ com.example.demo
┃ ┃ ┃ ┃ ┣ DemoApplication.java (役割:Spring Boot起動クラス)
┃ ┃ ┃ ┃ ┣ controller
┃ ┃ ┃ ┃ ┃ ┗ GameController.java (役割: )
┃ ┃ ┃ ┃ ┣ model
┃ ┃ ┃ ┃ ┃ ┗ Kazuate.java (役割: )
┃ ┃ ┗ resources
┃ ┃ ┃ ┗ templates
┃ ┃ ┃ ┣ index.html (役割: )
┃ ┃ ┃ ┗ result.html (役割: )
┗ ...(テスト、設定ファイルなど)...
この中で、
- Modelが
model
パッケージのKazuate.java
- Viewが
templates
フォルダ内のindex.html
およびresult.html
- Controllerが
controller
パッケージのGameController.java
に対応します。

3.1 プロジェクトを起動するためのクラス(例:DemoApplication.java)
以下のクラスは、Spring Bootアプリケーションを起動するための基本的な構成です。
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);
}
}
- アノテーション
@SpringBootApplication
Spring Bootアプリケーションのエントリポイントとして必要な設定を自動で適用するアノテーションです。 main
メソッド
Javaのプログラムの実行開始点で、SpringApplication.run()
メソッドを呼び出すことでSpring Bootアプリケーションが起動します。
このクラスを右クリックしてSpring Bootアプリケーションとして実行すると組み込みサーバー(Tomcatなど)が立ち上がります。ただし、ブラウザのアドレスバーにhttp://localhost:8080/
と入力してもindex.htmlなどを作成する前では以下のようなエラー画面が表示されることは前章で解説したとおりです。

3.2 Modelクラス(例:Kazuate.java)
JavaSEの卒業課題などで作成したような数当てゲームのクラスがあるとします。かなり簡略化して以下のようなクラスです。
package com.example.demo.model;
import java.util.Random;
public class Kazuate {
private int answer;
private String message;
public Kazuate() {
Random random = new Random();
this.answer = random.nextInt(10); // 0~9 の乱数
}
public void checkAnswer(int guess) {
if (answer == guess) {
this.message = "あたり";
} else if (answer > guess) {
this.message = "もっと大きいよ";
} else {
this.message = "もっと小さいよ";
}
}
public int getAnswer() {
return answer;
}
public String getMessage() {
return message;
}
@Override
public String toString() {
return "デバック用 [answer=" + answer + ", message=" + message + "]";
}
}
- ①このクラス名はなんですか?
あなたの答え: |
- ②フィールドはいくつあって、型は何で、名前は何ですか?
あなたの答え: |
- ③コンストラクタでは何をしていますか?
あなたの答え: |
- ④メソッドはいくつありますか? それぞれのメソッドの引数、戻り値の型、処理の内容を答えてください。
あなたの答え: |
- ⑤toString()メソッドの役割は何でしたか?
あなたの答え: |
これらの質問に答えられない場合、「新人エンジニア研修向けJava解説」に戻って復習の必要があります。
3.3 動作テスト用クラス
以下のようなテストクラスで、コンソール上で動かしてみることもできます。
package com.example.demo.model;
import java.util.Scanner;
public class KTest {
public static void main(String[] args) {
System.out.println("0-9の整数で数を当ててください!");
Scanner sc = new Scanner(System.in);
int guess = sc.nextInt();
sc.close();
Kazuate k = new Kazuate();
k.checkAnswer(guess);
System.out.println(k.getMessage());
System.out.println(k);
}
}
コンソールでの挙動を確かめたうえで、これをWebアプリケーションとして動かす(移植する)イメージで進めます。
4. Controllerと画面(View)
これまでJavaSEのコンソールアプリとして動かしていたKazuate
クラスを、Spring BootアプリケーションとしてWebブラウザで遊べるようにしてみましょう。
4.1 Controllerクラス
Spring Bootでは、以下のように@Controller
アノテーションと@GetMapping
などを使って、Controllerを実装します。MVCパターンでいえばControllerです。
package com.example.demo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import com.example.demo.model.Kazuate;
@Controller
public class GameController {
// GET リクエストで /game にアクセスされた場合の処理
@GetMapping("/game")
public String playGame(String guess, Model model) {
Kazuate kazuate = new Kazuate();
int answer = Integer.parseInt(guess);
kazuate.checkAnswer(answer);
// モデルにオブジェクトを追加してビューに渡す
model.addAttribute("k", kazuate);
return "result"; // src/main/resources/templates/result.html を返す
}
}
JavaSEの知識でこのクラスを読み解いてみましょう。
- ①このクラスの名前は何ですか?
あなたの答え: |
- ②このクラスにフィールドとメソッドはそれぞれいくつありますか?
あなたの答え: |
- ③このクラスのメソッド名、仮引数、戻り値を答えなさい。
あなたの答え: |
- ④@Controllerのような@から始まる記述をなんと呼ぶのでしたか?
あなたの答え: |
上記の質問に答えられない場合は、「新人エンジニア研修向けJava解説」に戻って復習の必要があります。
解説
- クラスの役割
このクラスは、ユーザーのリクエストを受け取り、適切なビュー(HTMLページ)を返す役割を持つコントローラーです。@Controller アノテーションを付けることで、Spring Boot がこのクラスをWebアプリのコントローラーとして認識します。 - ゲームの処理
- @GetMapping("/game") により、/game にアクセスするとこのメソッドが実行されます。
- playGame(String guess, Model model)の第1引数はフォームから渡されるguessという名前の文字列データ、第2引数はモデルといってデータをHTMLに表示するためのクラスですが後述します。
- Integer.parseInt(guess)で文字列データを数値に変換します。
- Kazuate クラスの checkAnswer(answer) メソッドを使って、入力値が正解かどうかを判定します。
- model.addAttribute("k", kazuate); により、kazuate オブジェクトをビューに渡し、HTML側で結果を表示できるようにします。
- "result" を返すことで、src/main/resources/templates/result.html が表示されます。
4.2 入力画面(View)
下図のような入力画面を作ります。

以下はThymeleafを使ったHTMLテンプレートファイルの例です。(src/main/resources/templates/index.html
)
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>数当てゲーム</title>
</head>
<body>
<h3>0-9の整数で数を当ててください!</h3>
<form th:action="@{/game}" method="get">
<input type="text" size="10" name="guess">
<button type="submit">送信</button>
</form>
</body>
</html>
- ①index.htmlという名前のHTMLファイルには特別な役割がありました。それはなんでしたか?
あなたの答え: |
- ②このフォームのhttpメソッドはなんですか? また、このメソッドの特徴はなんでしたか?
あなたの答え: |
- ③このフォームの部品には何がいくつ使われていますか? また、リクエストパラメータは送信先で何という名前で扱えますか?
あなたの答え: |
th:action="@{/game}"
は、Thymeleafの書き方で、実行時に/game
というパスを指します。元々英語の【at】には場所を指定する役割(at the station のように)があります。(メールアドレスに@が使われるのもその意味です)
先頭に"/"がついているのはルートという意味です。
今回で言えば、「http://localhost:8080/」の最後の"/"がルートです。したがって実行時のパス(URL)は「http://localhost:8080/game」となります。
なお、th:という属性はThymeleafの先頭2文字から来ています。
method="get"
と指定したので、ブラウザからGET /game?guess=5
のようにリクエストが送られます(例:5を入力した場合)。
4.3 出力画面(View)
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>結果画面</title>
</head>
<body>
<h1>ゲームの結果は!</h1>
<p th:text="${k.message}"></p>
<br>
<p th:text="${k}"></p>
</body>
</html>
th:text="${k.message}"
は、model.addAttribute("k", k)
で渡されたKazuate
オブジェクトからgetMessage()
を呼び出して表示します。メソッド名からgetが消えてMが小文字になっているルールに着目して下さい。プロパティアクセスするという重要な概念なので6章で後述します。th:text="${k}"
は、toString()
メソッドの結果を表示します。
5. Spring Bootの起動・停止
Spring Bootアプリケーションは、DemoApplication
といったメインクラスに@SpringBootApplication
を付与し、main
メソッドを実行することで内部的にTomcatサーバーが起動するのでした。
起動:複数の方法がありますが、一番のおすすめはBootダッシュボードから起動する方法です。最も簡単な方法で、Spring Bootアプリケーションの管理も楽になります。
- Eclipseのメニューで 「ウィンドウ」 → 「ビューの表示」 → 「その他」 → 「その他」 → 「Boot ダッシュボード」 を選択
- BootダッシュボードにSpring Bootプロジェクトが表示される
- 起動したいプロジェクトを選択して(再)起動や停止を選択

6. JavaSEとの比較
研修内容がWebアプリケーションに入ると急にファイル数やフォルダ構成が増え、「なんだか複雑…」と感じるかもしれません。
しかし、本質はJavaSEで今までやってきた「入力(Input)、処理(Process)、出力(Output)」と同じです。
違うのは、コンソール上ではなくブラウザのHTMLに表示される点、ControllerやViewといったファイルごとの役割分担が明確になっている点です。
6.1 入力の比較
System.out.println("0-9の整数で数を当ててください!");
Scanner sc = new Scanner(System.in);
int guess = sc.nextInt();
sc.close();
<h3>0-9の整数で数を当ててください!</h3>
<form th:action="@{/game}" method="get">
<input type="text" size="10" name="guess">
<button type="submit">送信</button>
</form>
6.2 処理の比較
Kazuate k = new Kazuate();
k.checkAnswer(guess);
Kazuate kazuate = new Kazuate();
kazuate.checkAnswer(answer);
model.addAttribute("k", kazuate);
return "result";
6.3 出力の比較
System.out.println(k.getMessage());
System.out.println(k);
<p th:text="${k.message}"></p>
<p th:text="${k}"></p>
JavaSEでは、Scanner
で入力を受け取り、クラスのメソッドを呼んで処理し、System.out.println()
で出力していました。
Spring Bootでは、<form>
で入力を受け取り、Controllerメソッドで処理を呼び出し、Thymeleaf(HTML)で結果を表示します。
第2章の今回はMVCパターンについて学びました。ここでこのあとの章の全体像を示すことにします。JavaSEを学んできたみなさんがJavaWebを学ぶ際に最初に面食らうのがHTMLとJava間のデータの受け渡しです。そのため3章と4章でその部分をまずは学びましょう。
第3章は「コントローラーの基本 〜 データをWebに表示するまで」です。
