Java Spring Boot ~Modelを実装する:MCVの「M」を実装する~

イントロダクション

前回はSpringframeworkを使用してMVCモデルのうち「C(Controller)」と「V(View)」を実装しました。Controllerから、View(HTML)に値を渡すところまで実装しました。

Controllerでは、次の2つの方法でレスポンスを返すことができることを学習しました。

  1. 文字列を返却する方法は下のように、返却値が文字列になっています。

    @RequestMapping("/")
    public String index(ModelAndView mav) {
    return "<html>"
            + "<title>Hello World</title>"
            + "<body><h1>こんにちは</h1>"
            + "<p>~PGボックスより~</p>"
            + "</body>"
            + "</html>";
    }
  2. HTMLを返却する方法は下のように、ModelAndViewクラスを返却します。

    @RequestMapping("/")
    public ModelAndView index(ModelAndView mav) {
    mav.setViewName("book");
    return mav;
    }

HTMLの場合は、Timeleafを使用しているので「resources/templates」の下に配置します。そして、例のコードでは「book.html」を返却します。

Modelを実装する

今まで、MVCモデルの「V」と「C」を学習してきました。ここら辺は、下の図で見ると簡単です。

全体の動きをイメージする

ブラウザで自分が運用しているウェブサイトの画面を開くことをイメージしてください。サーバーの設定ではJavaアプリケーションなので「WAR」ファイルとか「EAR]ファイルをアップロードすることになります。

PHPやHTMLをアップロードするようなサーバーを使ったときは、ドキュメントルート「/」のフォルダにPHPとかHTMLファイルを配置します。

Javaの場合は、リソース(画像ファイルやテキストファイルなど)を圧縮して先ほどの「WAR」や「EAR」にするのでドキュメントルートとかを意識しずらいですが、Javaでもやはりルートからディレクトリ構造ができています。

自分で作成したアプリをテストするときに「localhost:8080/」とブラウザのURLを入力して初期画面表示を行うと思いますが、「/」がルートを示します。

Javaコードでは「@RequestMapping("/")」のように実装しました。つまり、実際にファイルは配置していないけどURLでディレクトリ構造を作ることができます。HTMLファイルをここで指定するように配置するとURLとファイルの配置が結びついてわかりやすくなります。

この部分も自由に実装することができます。

Modelとは?

話をModelに戻します。上記の全体像を踏まえたところで、MVCの「V」と「C」はイメージがついていると思います。
今度は、MVCの「M」について学習します。

<例としてECサイトを見ます。>

よくあるECサイトを思い出してください。実際に存在する店舗の情報や、商品の情報をブラウザで見てクレジット決済を使用して購入できます。

この時に、「ウェブサーバー」と「商品」、「運送方法」に関して考えてみましょう。

1.ブラウザで商品を選択する

ブラウザで商品を選択して、購入します。この時に購入した商品は、元々どこにあったのでしょうか?商品だから「在庫」があることを確認する必要があります。

つまり、在庫にあった商品をブラウザで表示しているということです。この「在庫」を管理しているのはまた別のシステムになりますが、これはシステム同士で情報をやり取りする形で連携をしています。

具体的には、「在庫管理システム」と「商品受注システム」の連携が生じるということです。

2.商品をあなたに届ける

受注を受けたので、在庫が一つ減ります。しかし数字だけ減らしてもそれでは「商売」になりません。
受けた注文に対して「商品を届ける」というミッションが発生します。

これをどのように行うかは各社で方法がありますが、AMAZON社は配送するための仕組み=システムを構築しているようです。
ウェブシステムをメインで作成、管理しているところは「AWS」という会社で行っているらしいですが。。。

このような形で「ウェブシステム」→「アナログシステム(仕組み)」と連携して商品が手元に届きます。

Modelの存在

システム間で連携して、一連の作業を行っていることが多いのですが、ウェブシステムでも似たようなことが起こっています。
それは、MVCモデルでも同様です。

MVCの「V」でユーザーの操作を受け取ります。具体的には「商品を選択する」という操作を「リクエスト」という形でブラウザからサーバーへ通知を受け取ります。そして、サーバーサイドで何かしらの処理を行うのですが、これをちょっと分解してみてみましょう。

ウェブ画面の商品

ブラウザ(ウェブ画面)上の商品は明確に言うならば「イメージファイル」です。拡張子が「gif」とか「jpg」になっているファイルです。
これを、ユーザー(あなた)がクリックしたときに、サーバーへ「リクエスト(Request)」が送信されます。送信するのはユーザー(あなた)が使用しているPCです。もっと具体的に言うならば、ブラウザ(ChromeやEdge)です。

送信された「リクエスト」はサーバーへ届きます。言葉を変えるなら「V(View)」から送信されたリクエストを「C(Controller)」で受け取ります。
※HTML(View)にはクリックしたときにどこへ送信するか指定するタグやリンクを設定してあります。

この時に、どのコントローラーで受け取るのかはHTML側で決められているので、動きとしてはHTML→Javaソースとなります。これは今まで学習してきた「V」から「C」へリクエストが送信される部分に当たります。

本題のModelについて

「V」から「C」へリクエストが送信されるのはわかったけれど、「商品」の扱いが全然出てきませんね。

そうなんです。「商品」はDBや、サーバーに配置されているファイルを参照する必要があるので「C(Controller)」は、触らないことになっているのです。

なぜならば、それは「M(Model)」の役目だからです。コントローラーから受けたリクエストに応じて「何かしらの処理」を行うのが「M(Model)」の役目です。なので「ロジック(Logic)」とか呼ばれていることも多いです。

まとめると、下のように役割を分担した形が「MVCモデル」ということなのです。

  • M: ModelはDBやファイル(リソース)にアクセスして何かしらの処理を行う
  • V: Viewはユーザーの操作、入力を受け取りそれ(Request)をControllerに送る
  • C: ControllerはViewからのRequestを受け取りModelを呼び出しその処理結果をViewに返す

順番がごっちゃになっていますが、「MVCモデル」は上記のような分担を行った実装方法ということです。

Mmodelを作る

今までの解説のように、Modelは「何かしらの処理」を行うので、「1+1」の計算結果を返しましょう。
ちなみに「デフォルトコンストラクタ」はインジェクション(newしないでインスタンスを取得する)時に必要になるので作製しています。

public class SamplModel {
    /** デフォルトコンストラクタ */
    public SamplModel() {
    }

public int sampleLogic() {
        return 1 + 1;
    }
}

MVCの「M」を呼ぶ

MVCモデルの「V」「C」に関しては割愛しますが、「C」から「M」を呼び出してやる必要があります。
図にすると下のようになります。

ControllerからViewを呼び出すのには、「ModelAndView」クラスを使用します。このクラスはSpringframeworkの部品です。

そして、ControllerからModelを呼び出すのには、直接プログラムを書きます。
今回は、簡単に「new」してModelを呼び出しました。

このModelを呼び出す方法に関しては、依存性の注入という言葉があり、カタカナでは「インジェクション」といいます。
早い話が、Springframeworkであれば「@Service」アノテーションを使用してModelを呼び出す方法です。

ちなみに、JavaEEというテクノロジー(仕様)では「@Inject」で呼び出すことができます。「CDI」という言い方をしていますが結局は「インジェクト」です。

インジェクション

「インジェクト」を行うことを、このように言います。もう日本語も英語も区別がつきませんね(笑)

「@Inject」「@Service」などのアノテーションをつけてクラスのインスタンスを取得する方法です。
よくあるのはControllerクラスのフィールドにインスタンスを注入(インジェクト)する方法です。

具体的なコードは下のような形です。Serviceインターフェースを実装(implements)して実行することもあります。
ちなみに、ServiceインタフェースはSpringframeworkの部品です。

public MyControler /** implements Service */{
    /** サービス */
    @Service // Springの場合
    MyService service1;

    public void execute() {
        // サービスの処理を呼び出す。
        service1.somethingTodo();
    }
}

アノテーションについて

アノテーションはフィールドにつけたり、クラスやメソッドにつけたりできます。まとめた言い方をすると「自身を含めた、クラスの要素(プロパティ)につけることができるインターフェース」のことです。

具体的にはアノテーションを作るときは下のように書きます。インターフェースなんですね。

@Target(ElementType.TYPE)
public @inteface MyAnnotation {
}

細かい作り方は、参考にしたサイトを参照ください。

<<< 前回

Java SpringBoot + Thymeleaf 画面を作成する ~ControllerからHTMLまで~

イントロダクション

前回はSpringBootでの開発セットアップを行いました。

前回の状態では、エラーページしか確認できませんでした。

これは、サーバーが起動していることを確認するという意味で、必要な確認なのですが。。。動かないのでは面白くありません。

SpringBoot + Thymeleafで画面を作る

毎度おなじみ、「ハローワールド」をやってみようと思います。

ちなみに、「Thymeleaf」は画面(HTML)とMVCのC(コントローラー)を接続するツールです。チュートリアルもあるのでわかりやすいです。

そして、やってみました。こんな感じです。※クラス名、Eclipseのバージョンなどが違いますが。。。

作成するもの

  1. Javaファイル(コントローラークラス)
  2. HTMLファイル(Thymeleaf使用)

準備

まずは、作成して動かすことに注力します。
プロジェクトを作成したら初めに「SampleWebAppApplication」というクラスが作成されていると思います。
※自動生成されているクラスがあるはずです。

このクラスがアプリケーションを起動するクラスです。しかし、このクラスはいじる(修正する)必要がありません

アプリを動かすために

自動生成された「SampleWebAppApplication」はアプリケーションを起動するためのクラスなので、本当にアプリを起動するだけなのです。

起動確認するときに、エラーページしか出ないのは表示するものが何もないからです。

そして、Springframeworkを使用してのウェブアプリケーションはMVCモデルを使用しています。つまりは、「Model(処理クラス)とView(画面)とController(リクエストハンドラー)に分けて処理を分担した形で実装しましょうね」というやり方を採用しています。

今度はMVCの「C]を作りましょうということです。

Controllerクラスを作る

それでは、早速コントローラークラスを作成します。まずは、ルールがあるのでそれに注意します。
先ほど自動生成されたクラス「SampleWebAppApplication」はパッケージ「com.example.demo」というパッケージに作成されています。

パッケージはウィンドウズでいうところの「フォルダ」に相当します。上に貼り付けているものは、パッケージを表示していいます。

一番上にある「src/main/java .... 」の部分はフォルダ構成上下のようになっています。

  1. プロジェクトのフォルダがあります。
  2. その中に、srcというフォルダがあります。
  3. 同様にmainというフォルダ
  4. javaというフォルダ
  5. そして、ここからが「パッケージ」と呼ばれるフォルダになります。「com」フォルダ
  6. 「example」フォルダ
  7. 「demo」フォルダ

このようにフォルダ構成が出来上がってるのですが、これを「パッケージ」と呼び下のように表現することで、どのファイルのクラスを参照するかわかるようにしています。
Javaのプログラムでいうと「インポート文」がそれにあたります。

import con.example.demo.*;

上のインポート文は「con.example.demo」パッケージにあるクラスを全てインポートするという意味です。

Controllerのみで動かす

パッケージに関して意味が分かったところで、上記で記載した「ルール」に関してお話ししたいと思います。
自動生成されたクラス「SampleWebAppApplication」よりも下のパッケージ内にコントローラーなどの読み込むクラスを作成するというルールがあります。

なので、今回作成するコントローラークラスはパッケージ「com.example.demo.controller」に作成することにします。
パッケージの作成方法は下のように行います。

  1. 作成するパッケージの親になるパッケージを右クリック※com.example.demoパッケージを右クリックしました。
  2. そして、「パッケージ」という文言が見つかればよいのですが、残念ながら表示されていませんので「その他」をクリックします。すると下のようなウィンドウが開きます。
  3. そこでパッケージを選択してやれば作成できるというところです。

さらに、ここからクラスも作成します。手順は上と同じですが、選択するものが「クラス」になります。

そして、ここでは「HelloController」というクラスを作成します。

package com.example.demo.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;

@RestController
public class HelloController {

    @RequestMapping("/")
    public String index(ModelAndView mav) {
        return "Hello World";
    }
}

<表示結果>

ここでは、HTMLの作成は必要がありません。

実は、上記の「@RequestMapping」アノテーションを付けたメソッドは返却文字列を指定した場合はHTMLになります。なので下のようにコードを変更してやると。。。

@RequestMapping("/")
public String index(ModelAndView mav) {
    return "<html>"
            + "<title>Hello World</title>"
            + "<body><h1>こんにちは</h1>"
            + "<p>~PGボックスより~</p>"
            + "</body>"
            + "</html>";
}

<表示結果>

このように表示できます。しかし、「もっとオシャレに!」「もっと機能的に!」ということを考えるとHTMLファイルを使用して動かした方が効率的です。

もちろん、ウェブデザイナーさんの協力を頂き、その実力を発揮してもらうならナチュラルなHTMLがベストです。JSPなどは専門外のはず。。。

View(HTML)を作成する

ウェブサーバーを起動して、ルートにあたるURL「localhost\:8080」にアクセスしたので次は、Controllerクラスを起動して、HTMLファイルを参照する形にプログラムを書き換えます。

実行動画

実装内容

そこで「Thymeleaf」というフレームワークを使用します。これはコントローラーとHTMLを橋渡しするためのフレームワークです。
具体的に見ていきましょう。まずはHTMLをみてみましょう。

<!DOCTYPE html>
<html>
<head lang="ja" xmlns="http://www.thymeleaf.org">
    <meta charset="UTF-8">
    <title>Sample Index Page</title>
</head>
<body>
    <h1>Recommended index</h1>
    <p>おススメの漫画・アニメを検索できます。</p>

</body>
</html>

上のようなHTMLを作成します。この状態ではコントローラーとのやり取りがない状態です。
しかし、まずはこの状態で動かしてみます。作成したHTMLファイルは「src/main/resources/templates」フォルダの下に作成しましょう。

そして、コントローラーも書き換えます。これは、もともと返却値にString(文字列)を設定していましたが、これをModelAndViewクラスに変更しています。もちろんこれらのメソッドは、オーバーライドしているのと同じ形で、「@RequestMapping」アノテーションに紐づいています。

つまり、想定されているメソッドの返り値ということです。そんなわけで、ModelAndViewにHTMLファイルの名前「book」をセットして返却してやれば次のように動いてくれるというわけです。

  1. ルート「/」にアクセスする(localhost:8080)
  2. templateフォルダ以下の「book」というHTMLファイルを取得する
  3. ブラウザに表示
@RequestMapping("/")
public ModelAndView index(ModelAndView mav) {
    mav.setViewName("book");
    return mav;
}

<実行結果>

次は、値を渡す

このように動いたところで、コントローラーから値を渡すことを考えます。

コントローラーからHTMLへ。。。

今回のJavaプログラムはサーバーサイド・プログラムなので(※クライアントでも動かすことができます。)サーバー側での処理を行うことができますが、クライアント(ブラウザ上)でのプログラムはJSとかHTMLに任せることになります。

なので、サーバーでの処理結果をクライアントに渡すにはちょっとテクニックが必要になります。
具体的には、以下の通りです。

  1. リクエストパラメータを使用する
  2. レスポンスに処理結果を埋め込む(渡す)

こんなことを言われても「???」となってしまう人は正常です。ご安心ください。

Controllerクラスを見る

具体的に下のようなコードで処理の結果を渡します。プログラムは微妙に修正しています。
<Java>

@RequestMapping("/")
public ModelAndView index(ModelAndView mav) {
    mav.setViewName("book");
    mav.addObject("key", 12);
    return mav;
}

View(HTML)をみる

<HTML>

<!DOCTYPE html>
<html>
<head lang="ja" xmlns="http://www.thymeleaf.org">
    <meta charset="UTF-8">
    <title>Sample Index Page</title>
</head>
<body>
    <h1>Recommended index</h1>
    <p>おススメの漫画・アニメを検索できます。</p>
    <p th:text="${key}">ここに値が入ります。</p>

</body>
</html>

<実行結果>

赤枠で囲った部分がJava側からHTMLへ渡した値です。

まとめ

SpringBootを使用して、画面を作成しとりあえず動かしてみました。ここまででMVCモデルの「C(Controller)」と「V(View)」がわかったと思います。
残りの「M(Model)」は?と疑問に思うかもしれません。次は、このModelに関して記述したいと思いますが、ちょっと時間がかかります。

中途半端ではありますが、とりあえずは、ここまでに致します。

でわでわ。。。

<<< 前回 次回 >>>

Java SpringBoot セットアップ ~Eclipse All in Oneでやると早い~

SpringBootの開発 セットアップ

SpringBootのセットアップを行うのに、いろいろな手順があり、混乱するので(自分の行った中で)もっとも簡単な方法を記載します。

使用するIDE(開発ツール)はEclipseのAll in Oneです。

これを使うと、GUIでサクッと環境構築ができるというわけです。以下手順を記述します。

実行したことの動画

SpringBootとは

SpringBootはフレームワークと呼ばれるカテゴリに属するものです。「フレームワーク」はアプリケーションを作成するときに1~10まですべてを作らなくても必要な部分を作成すれば、アプリケーションとして動かすことができる便利ツールです。SpringBootSpringframeworkを起動できる、機能を備え付けたパッケージのようです。

詳細はリンク先に記載されていますが、まとめると「Springframeworkで作ったアプリケーションを起動できる」ということです。

初心者向けの説明

具体的には、Springframeworkはウェブアプリケーションを作成するのに「MVCモデル」という形の設計方法を使用しています。現代のウェブシステムはほぼこの形にになっています。

MVCモデル

この形を作ったうえでMVCに当たる各部品を自分で作成すれば、あとは動かすことができる。というものです。
言葉よりもイメージ図がわかりやすいと思います。ちなみに「Container」は「Controller」の間違いです。

フレームワークの役目

上記のように、各MVCに当たる部分を作成すればよいのですが、部分的に見ても全体的なイメージが付きません。
なので、その部分を解説します。上記のイメージを見てもらうとMVCのそれぞれに矢印がありますが、この矢印部分にはプログラムの処理が入っています。
この矢印の部分をフレームワークが行います。

Viewから話を進めていきます。

  1. 画面(View)空の入力データをControllerに送る時HTMLではサブミットを行います。
  2. サブミット=リクエストの送信をしたら、指定した、クラス(Contoller)が、リクエストを受け取ります。
  3. 受け取ったリクエストをクラス(Controller)が担当するクラス(Model)に処理を渡します。
  4. 担当クラス(Model)が処理を行います。
  5. クラス(Controller)がリクエストを画面(View)に戻します。

注意点

ちなみに、プロジェクト作成時に必要なものをチェックしないとうまく動かなかったので、そこが注意点です。

大まかな手順

  1. プロジェクトを作成するときにSpringBootのスタータープロジェクトを作成する
  2. プロジェクト作成時に、ThymeleafとDB(H2DB)とSpringWebを追加する
  3. プロジェクト作成後にPOMファイルを「Maven install」で実行する
  4. Mavenプロジェクトの更新

プロジェクトの作成

Eclipseを起動してから、下のようにプロジェクトを右クリックし「新規」をクリック以下の手順に従います。

  1. Springスタータープロジェクトを選択し、「次へ」をクリック

  2. プロジェクトの名前などを入力する。使用するJDKによって「Javaバージョン」の値を変更する
     ※JDK1.8であれば「8」を選択する

  3. 使用するDBやフレームワーク(ツール)を選択する、今回はDBに「H2DB」、画面の作成に「Thymleaf」を使用するのでそれぞれのチェックボックスにチェックを入れる
    そして、Spring Webにチェックを入れる

  4. 最後に完了を押下する

※画像には「MySampleWebbApp」とあったが、「SampleWebApp」プロジェクトを作成した形で手順を進めます。

作成したプロジェクトは下のような形でEclipseのプロジェクトエクスプローラー、もしくは、パッケージエクスプローラーに表示されるはずです。
作成後のプロジェクト名が「MySampleWebbApp」になっていますが、「SampleWebbApp」での作成も確認しています。

プロジェクトを作成したばかりの状態では、バックグラウンド処理で何かしらのインストールが走っているので、ちょっと待ちます。

最後にプロジェクトを右クリック、実行、Spring Bootアプリケーションをクリック
これだけで、セットアップは完了です。

そして、ブラウザを開き、http://localhost:8080 にアクセスします。
ここでは、エラーページしか出ませんが、Tomcat(Webサーバー)が動いていることを確認するのが目的なのでこれでよいのです。

まとめ

これで、開発を行うために必用な環境がセットアップできました。つまり、次のものが動いていることを確認できました。

  1. ウェブサーバー(Tomcat)の起動確認
  2. ブラウザ(ChromeやEdgeなど)での表示確認

次は、これに自作のページを追加していきます。

次回 >>>