JSP/Java ServletによるMPA開発
お知らせ:2024年度の情報システム設計では「GitHub - HazeyamaLab/systemdesign2024」というリポジトリが教材として公開されていて、なんと解説もリポジトリの中に最初から入っています。下記の解説は2023年度以前の教材に関するものです。
この記事では、東京学芸大学ソフトウェア工学研究室が情報システム設計(東京学芸大学 情報教育(E類)の科目)の教材として公開しているリポジトリ「GitHub - HazeyamaLab/system-design-docker-stuinfo」(以下『stuinfo』)を用いながら、JavaServer Pages (JSP)およびJava Servletを用いたマルチページWebアプリケーション開発の流れについて説明します。なおmgn901.iconはstuinfoの開発者ではありません。
stuinfoについて
2023年度の情報システム設計では、課題としてJavaを用いたWebアプリケーションの開発を行うことになっていますが、stuinfoはその流れの理解を促す教材として用意されたリポジトリです。
stuinfoは、設計としてMVCモデルを、フレームワークとしてJSPおよびJava Servletを採用しているWebアプリケーションとなっています。
この記事では、まず今までの授業で書いてきたプログラムとWebアプリケーションの間にある違いや、MVCモデルおよびオブジェクト指向プログラミングに対する理解を確認します。その後MVCモデルおよび3層アーキテクチャの各要素とstuinfoの各要素を結びつけることを通して、Java Servletを用いたWebアプリケーションの全体像をつかむことを目指します。
今までの授業で書いてきたプログラムと、Webアプリケーションの間にある違い
1年次のプログラミング4科目8単位や、2年次の応用プログラミングでは、次のようなプログラムを書いてきました。
入力に対して決まった処理を行い、その結果を出力するようなプログラム。
入力されたデータ構造に変更を加え、その結果を返すようなプログラム。
GUIは備えておらず、CLIやIDEから処理を実行する。
Webアプリケーションは、1年次や2年次に書いてきたような、実際の処理を行うプログラムに対して、Webブラウザを通して提供するGUIを備えたものと捉えることができます。
また、Webアプリケーションとは何かを読んでみてください。
なぜMVCモデルが必要なのか?
3層アーキテクチャやMVCモデルの意義を読んでみてください。MVCモデルを3層アーキテクチャの中に落とし込んで説明する記事で、3層アーキテクチャやMVCモデルの必要性や役割を理解することができます。
注意: MVCモデルは3層アーキテクチャの一部として開発されたアーキテクチャではないことに注意してください。今回は理解のしやすさのために3層アーキテクチャを持ち出して説明をしているだけです。このような説明をしているのは、MVCモデルと3層アーキテクチャが同じ動機でつくられたからではありません。MVCモデルがGUIをもつアプリケーションの設計パターンであることと、3層アーキテクチャの3層にプレゼンテーション層とビジネスロジック層が含まれていることを踏まえると、MVCモデルはプレゼンテーション層とビジネスロジック層をより具体的に規定するものだといえるからです。
保守性の高いソフトウェアのためには、ソフトウェアを構成するプログラムのモジュール間の凝集度の高さと結合度の低さによって実現される、各モジュールの機能独立性の高さが求められます。MVCモデルはソフトウェアを、全体の制御、情報処理、ユーザに対する表示のそれぞれに専念するモジュールに分割することで、機能独立性の高さを実現します。
MVCモデルの各要素とstuinfoの各要素を結び付け、処理の流れを理解する
3層アーキテクチャやMVCモデルの意義には、MVCモデルの各要素とその関係を3層アーキテクチャの中に落とし込んだ図を載せました。
https://gyazo.com/70801a0e6b228ee0573cbc748ff1c4fe
stuinfoのプログラムは/src/main/(先頭の/はリポジトリのルートディレクトリとする・以下同様)の下に格納されていますが、その下の各ディレクトリの内容をMVCモデルの各要素に結び付けると次のようになります(本記事に無関係なディレクトリは省略しています)。
webapp/WEB-INF: View
JSPが格納される。
JavaServer Pages (JSP)はユーザに表示される画面を規定するHTML文書を生成する仕組みである。
ユーザが見る画面に使用されるJSPはHttpServlet(後述)の制御によって選択される。
java
servlet: Controller
HttpServletを継承したクラス(サーブレット)が格納される。
ユーザはJSPを通してHttpServletに入力を与え、HttpServletはそれを受けてWebアプリケーションの制御を行う。
control: Model
ビジネスロジックを担当するクラスが格納される。
1・2年次に書いたような、入力されたデータに対する処理と結果を返すプログラムが含まれるのは、この部分である。
controlという名前が付いているが、実際はビジネスロジックを担当しDAOとのやりとりを伴うため、ControllerともModelともつかない気がする。mgn901.icon
beans: Model
クラス図に載るモデルオブジェクトのクラス定義(モデルクラス)が格納される。データベースのテーブルに保存されるレコードを、フィールドとメソッドをもつJavaのオブジェクトとして表現する。
DAOから取り出され、control配下のクラスで変更が加えられ、DAOを通してデータベースに保存される。
dao: DAO
utility.DriverAccessorを継承したクラスが格納される。
モデルオブジェクトをデータベースに読み書きする役割を果たす。
JavaプログラムによるビジネスロジックとSQLで操作するデータベースとの間の橋渡しの役割を果たす。DAOのメソッドを呼び出すことでデータベースへの問い合わせを行えるようにし、Javaの標準的なデータ構造を通してデータベースから渡されるクエリ結果を処理できるようにする。
オブジェクト指向とクラス図
上記により、stuinfoのプログラムの処理の流れの概観をつかむことができると思います。しかし、オブジェクト指向やオブジェクト指向プログラミングが初めての方は、モデルオブジェクトの役割がわからないために理解に苦しむ部分があるかもしれません。
オブジェクト指向やオブジェクト指向プログラミングが初めてである方は、自動販売機でオブジェクト指向を学ぶを読んでみてください。
Javaはオブジェクト指向プログラミングを行いやすくしたプログラミング言語であり、基本的にクラスの組み合わせによってプログラムを組み上げていきます(クラスベース)。HttpServletも、controlディレクトリ配下のクラスも、DAOも、みなクラスであり、そこからインスタンス化されたオブジェクトは現実の機械のように、内部状態と、外部からの操作を受け付ける窓口を備えています。
しかし、モデルオブジェクトはHttpServletのような機械とは少し異なります。
モデルオブジェクトは、ビジネスロジックの直観的な記述を可能にするためにつくるものです。オブジェクトモデルを構築し、それを踏まえてモデルクラスを定義し、データベースのテーブルやDAOについてはモデルオブジェクト(モデルクラスのインスタンス)を扱うことを念頭に記述することで、ビジネスロジックはまるでモデルオブジェクトそのものを操作しているかのように記述できるようになります。
オブジェクト指向(オブジェクト指向プログラミングではないことに注意)の考え方を取り入れてソフトウェアを開発する場合、ソフトウェアで扱われる概念をクラス図上で整理します(オブジェクトモデルの構築)。
例えば写真アルバムのアプリをつくる場合、そこで扱われる対象は「写真」と「アルバム」の2種類の概念になると思います。その場合は写真クラスとアルバムクラスの2つを用意することになります。
また、データベースのテーブル定義はクラス図で定義したオブジェクトに対応するように行います。
そして、DAOはデータベースからのクエリ結果をモデルオブジェクトに変換したり、モデルオブジェクトを変更する要求をSQLのクエリに変換したりするように記述します。
これにより、DAOを通してデータベースからモデルオブジェクトを取り出し、それに対して直観的に変更を加え、DAOを通してデータベースに保存することが可能になります。ビジネスロジックはモデルオブジェクトの取得、生成、変更に集中できるようになります。
stuinfoの動作
stuinfoの全体像の説明は以上ですが、stuinfoの詳細な動作を説明しているページを用意しています。
課題の進め方
課題ではモデル側から書き始めるとよい mgn901.icon
モデルとDAOから書き始めて、少しずつビューに近づいていくのが良いと思います。つまり処理の本質を担当する部分から書いた方が良いということです。
ビューから書き始めると、モデルをそれに合わせたくなるので、せっかくつくった設計が意味をなさなくなってしまいます。Webアプリケーションを、処理のためのプログラムにGUIをくっ付けたものであると捉える場合、ビューよりもモデルの方が本質的で重要度が高いはずです。いわば些末ともいえるビューが、本質的なモデルに頭を下げさせることがあって良いのか?とmgn901.iconは思います。
詳しい人向けの補足: ライブラリ等を書く場合とは別の話です。
ビジネスロジックの設計と実装
要求されている機能を満たすのに必要なものを用意すればよいでしょう。構造化分析(Structured Analysis)などによって構築できる機能モデルが参考になると思います。
stuinfoのように、学生情報の登録と、登録した学生情報の1件検索・表示しか行わないのであれば、ビジネスロジックのためのメソッドは2つだけになります。
何をどのように(1件だけなのか、複数件なのか)表示できるようにしたいのか、何を変更できるようにしたいのかを考えて、必要なビジネスロジックを洗い出しましょう。
JSPとサーブレットの実装
ビジネスロジックに対応するようにJSPとサーブレットを用意すればよいでしょう。この際JSPとサーブレットは1対1で対応するようにします。
モデルオブジェクトの変更を伴うビジネスロジックを呼び出すサーブレットの場合は、処理に成功したか失敗したかをユーザに伝えるために、1つのサーブレットに対してJSPが複数となる場合もあります。