学習用Webフレームワーク作成 その1(リベンジ)



フルスタックフレームワークを目指すべく、「EzJDBC」い続いて、プレゼンテーション用フレームワーク(EzServlet)を開発したのでリファレンスを記述します。
JAVA EEを隠蔽し、「HTMLテンプレート」+「POJO」で開発するしたフレームワークです。


EzServletとは


 □概要
 □プログラム構成
 □URLパターン
 □HTMLの説明
 □Viewクラスの説明
 □Controllerクラスの説明
 □FW専用タグの説明
 □FW専用クラスの説明
 □FAQ
 □最後に

概要
WEB開発における「JAVA EE」の煩雑な作業を完全に隠蔽し、利用者がビジネスロジックに、専念できるWEBフレームワークです。以下に、「EzServlet」の特徴を記述します。


1.学習コストが低い
 EzServletの最大の特徴は、なんと言っても「学習コスト」の低さにあります。
 EzServletは、他のフレームワークに依存しないため、他のFW知識が一切不要です(*1)。
 また、完全POJO開発ですので、「JAVA EE」の知識も一切不要となります(*2)。


2.設定が最小限
 唯一の設定は、URLに対応する「トップページ(のHTMLのPATH)」の設定です。
 通常のプロジェクトであれば、1行ないし2行程度の記述で済みます。
 設定の記述量は、Strutsの「100分の1」から「1000分の1」になります。
 ⇒ Strutsと比べる時点でネタです。



3.規約が最小限
 規約は、以下の程度です。詳細は別途説明いたします。
 ・各種リソース(HTMLやClass)の名称を一致させる。
 ・HTMLタグのname属性とプロパティおよびメソッド名を一致させる。


4.アノテーションが不要
 アノテーションによる設定は一切ありません。


5.専用タグ、専用クラスが少ない
 フレームワークを利用するために覚える必要のある「HTML専用タグ」「専用クラス」が、
 他のフレームワークに比べて圧倒的に少ない。
 専用タグ6個,専用クラス7個。


6.ツールが充実
 WEB開発を支援する「scaffold」や「エディター」が充実しています(*3)。


(*1)ファイル・アップロードに「commons-fileupload」を利用していますが、完全に隠蔽しています。
(*2)フレームワークの2つある拡張ポイントの1箇所で、サーブレットの知識が必要になる場合がありますが、全開発者が知る必要はありません。また、この拡張ポイントが利用される事は、あまり無いと思います。もう1つの拡張ポイントで、大体のことが可能になるためです。
(*3)ツールを利用しなくても、簡単に開発することが可能です。



プログラム構成
まず、EzServletを利用してWEBシステムを開発する際に、作成するリソースの構成を説明します。
詳細については、サンプルを元に説明いたしますので、ここでは各リソースの概要をつかんで下さい。


1.HTML
 画面のデザイン(モックHTMLを利用する事も可能)
 HTMLに、7種の専用タグを追記(*1)することにより、動的な画面を作成することが出来ます。
 (*1)HTMLに専用タグを記述しても、HTMLをブラウザーで確認する際に、デザインが崩れません。

2.Viewクラス
 画面(HTML)の入出力項目を保持するクラスです。
 HTMLタグ&専用タグの「name属性」と同名のプロパティを持つクラスです。
 ネストした画面は、インナークラスを格納するListを、プロパティとして持ちます(*1)。
 また、入力項目の検証メソッドも、このクラスに記述します。
 (*1)画面のネストに制限はありません。

3.Controllerクラス
 画面の遷移を制御するクラスです。
 要求のあった画面(HTML)に対応したControllerクラスが呼び出されます(*1)。
 押下された、HTMLのボタン(リンク)の「name属性」と同名のメソッドが呼び出されます。
 (*1)Viewクラス:Controllerクラス = 1対1 or n対1で作成します。

4.定数クラス
 画面(HTML)に、表示するラベル(表示項目)のプロパティキーを定数として管理するクラスです。
 プロパティファイル(*1)で表示項目を管理しない場合、このクラス不要です。
 (*1)キーに対応するプロパティファイルは、任意に指定可能です。未指定の場合は共通を参照。


URLパターン
EzServletでは「固定URL」を採用しています。
固定URLとは、アプリケーションの開始から終了まで、URLが変わらないこと意味します。
EzServletは、URLを固定にすることにより、画面遷移とURLの不一致をなくします。



URLパターン
http(s)://localhost:8080/コンテキストルート/任意文字列/ロケール(ja,en等)
EzServletは、上記ルールのURLパターンからのアクセス(GET要求)があると、「url.任意文字列」をキーに、表示要求のあった画面(HTML)を特定し、画面(HTML)に対応するControllerクラスのindexメソッドを呼び出します。その後は「POST」で要求を処理します。
設定方法は、ソースフォルダー配下の「EzServlet.properties」に、下記の様に設定します。


URLが「http(s)://localhost:8080/コンテキストルート/login/ja」で、ログイン画面を表示する場合

url.login=jp/co/sample/Login.html
URL設定は「アプリケーション」毎に、複数設定することが可能です(例:一般用と管理者用)
URLに「ロケール」を指定すると、画面の「表示項目」や「メッセージ」等を出力する際に、指定されたロケールに対応するプロパティファイルを参照します。
ロケールに指定が無かった場合は、ブラウザーのデフォルト・ロケールを使用します。



サンプルアプリを作成して、各リソースの説明を行います。
作成するサンプルアプリは、「足し算」アプリです。
機能は、2つのテキストボックスに入力された値を加算し、結果を同一画面に表示するサンプルです。
HTMLの説明
HTML名「add.html」


<html>
  <head></head>
  <body>
  <form method="post">
    <input type="text" name="value1" value="">+
    <input type="text" name="value2" value="">=
    <tg:out name="total">0</tg>
    <br>
    <input type="submit" name="execute" value="計算">
  </form>
  </body>
</html>
どうですか? HTMLタグをご存知の方であれば、上記HTMLが、どの様な画面か一目瞭然だと思います。
例えば、<input>タグの「value属性」に、文字エスケープの設定等も入りません。
この、ほぼ「純粋なHTML」であることが、HTMLテンプレートのメリット(*1)です。


青字のタグは、EzServletの専用タグで、プログラム実行時に<tg:out name="total">から</tg>で囲まれた箇所は、Viewクラスの「totalプロパティ」の値と置き換えられる「出力項目用タグ」です。
<tg:out></tg>の間には、モックHTMLとしてのダミー値を記述します。


専用タグは、後述する「EzServlet用HTMLエディター」で補完可能です。
また、一定のルールの元、モックHTMLに、専用タグを自動補完するEclipseプラグインもあります。
(*1) 複雑な画面ほど、可読性の高さを感じて頂けると思います。


Viewのクラス説明

クラス名「Add.java」 クラス名は、HTMLファイル名の「キャメル記法」になります。


public class Add implements Serializable {
   /** add.htmlのテキストボックス「value1」に対応するプロパティ */
   public String value1;
   /** add.htmlのテキストボックス「value2」に対応するプロパティ */
   public String value2;
   /** add.htmlの出力項目「total」に対応するプロパティ */
   public int total;

   /** 入力値検証メソッド */
   public void validate(EzResponse response) {
      boolean error = false;
      // 入力値検証処理
      . . .
      if(error) {
         // EzResponseに表示する画面(HTML)のビュークラスをセットします。
         response.setPage(this);
         // 後続処理を中断し、エラー画面を表示します。
         response.finish();
      }
   }
}

Viewクラスは、HTMLのテキストボックス及び出力項目に対応するプロパティを持つクラスです。
入力値の検証(validate)も、このクラスに実装します。
下記に、Viewクラスの「プロパティ」と「メソッド」について説明します。


1.Viewのプロパティ

   /** add.htmlのテキストボックス「value1」に対応するプロパティ */
   public String value1;
   /** add.htmlのテキストボックス「value2」に対応するプロパティ */
   public String value2;
   /** add.htmlの出力項目「total」に対応するプロパティ */
   public int total;
value1は、Add.htmlの<input type=”text” name=”value1”>の値を、設定するプロパティです。
value2は、Add.htmlの<input type=”text” name=”value2”>の値を、設定するプロパティです。
totalは、Add.htmlの<tg:out name=”total”>0</tg>の位置に値を出力するためのプロパティです。


2.validateメソッド
valideteメソッドは、画面の入力値(value1,value2)の入力値検証を行うメソッドです。
このメソッドは、Cotrollerクラスより明示的に呼び出します。


validateでエラーが発生した場合、Controllerクラス内で、エラー有無を判別するのif文が入ると、可読性が下がるため、検証エラーが発生した場合は、後続処理をスルーする下記の機能があります。

         // EzResponseに表示する画面(HTML)のビュークラスをセットします。
         response.setPage(this);
         // 後続処理を中断し、エラー画面を表示します。
         response.finish();
上記ソースは、検証エラーが発生した場合の処理になります。


EzResponceクラス(response)は、クライアントへの返答(応答)クラスになります。
responseに、画面(HTML)に対応するViewクラスを設定「response.setPage(this)」することにより、
クライアントに表示する画面(HTML)を指定したことになります。
responseのfinishメソッドは、後続処理を中断し、「エラーメッセージ」を設定された画面(HTML)に表示します。
(*1) EzResponseの詳細については、次の「Controllerクラス」の時に説明いたします。



Controllerのクラス説明

クラス名「AddController.java」 クラス名は「Viewクラス名 + Controller」になります。


public class AddController {
  
   /** セッション */
   public EzSession session;
   /** リクエスト */
   public EzRequest request;
   /** レスポンス */
   public EzResponse response;

   /** 初期画面表示 */
   public void index() {
      // クライアントに初期表示する画面(HTML)に対応するビュークラスを生成しセット。
      response.setPage(new Add());
   }

   /** executeボタンが押下された時に呼び出されるメソッド */
   public void execute(Add add) {
      // 画面の入力値をビュークラス(Add)にセットします。
      request.copy(add);
      // 入力値の検証を行います。
      add.validate();
      // 入力値を加算し、合計をAdd.totalにセットします。
      add.total = Integer.parseInt(add.value1) + Integer.parseInt(add.value2);
      // クライアントに表示する画面(HTML)に対応するビュークラスをセットします。
      response.setPage(add);
   }
}

画面の遷移を制御するクラスです。
下記に、Controllerクラスの「プロパティ」「メソッド」について説明します。


1.EzSessionクラス

   /** セッション */
   public EzSession session;
EzSessionクラスは、アプリの利用が開始されてから終了するまで、利用可能なオブジェクト格納領域です。例えば、ログインしてから、ログアウトするまでの間、保持する必要のあるオブジェクト(ユーザー情報等)を格納する場合に利用します。


何気なくうれしい機能?
EzServletでは、タブブラウザーに対応しておりますので、タブ毎にEzSessionが作成されます。
1ブラウザー、複数タブで、同一のアプリケーションにアクセスしても問題は発生しません。



2.EzRequestクラス

   /** リクエスト */
   public EzRequest request;
EzRequestクラスは、クライアントからの要求から返答(応答)まで、利用可能なオブジェクト格納領域です。例えば、クライアントから、ログイン要求があってから、クライアントにトップページを表示するまでの間を指します。
クライアントから、要求があった場合は、このクラスに画面入力値がセットされます。


何気なくうれしい機能?
EzRequestには、画面入力値が、前回の状況と異なっているか(入力値の打ち変えが発生したか)を判別する「isChange」メソッドがあります。
また、ブラウザーの「戻る」ボタンが押されたかを判別する「isSynchronizing」メソッドもあります。その他色々…



3.EzResponseクラス

   /** レスポンス */
   public EzResponse response;
EzResponceクラスは、クライアントへの返答(応答)クラスになります。
クライアントへ表示する画面の設定、またはクライアントへダウンロードファイルの送信を行うクラスです。また、後続処理を中断し、設定された画面を即座に表示するための機能(finishメソッド)をもちます。


何気なくうれしい機能?
EzResponseには、クライアントにダウンロードファイルを送信するための「getOutputStream」メソッドがあります。EzResposeより取得したOutputStreamが、実際に利用されない(出力されない)場合は、クライアントへ、画面を表示することが可能です。
具体的にいうと、コントローラーからサービスクラスのメソッドに、「OutputStream」を受け渡し、サービスのメソッド内で、ダウンロード対象データが無いと分かった場合は、画面にエラーメッセージを表示することが可能になります。つまり、サービスから「java.io.File」を返す必要がなくなります。



4.indexメソッド

   /** 初期画面表示 */
   public void index() {
      // クライアントに初期表示する画面(HTML)に対応するビュークラスを生成しセット。
      response.setPage(new Add());
   }
indexメソッドは、クライアントよりURL(GET要求)があった場合に、呼ばれるメソッドです(*1)。
(*1) 呼び出されるクラスの特定は、上述の「URLパターン」の章を参照して下さい。

      // クライアントに初期表示する画面(HTML)に対応するビュークラスを生成しセット。
      response.setPage(
上記ソースは、クライアントに表示する画面(Add.html)に対応するViewクラスを生成(初期化)しresponseのsetPageメソッドに設定することで、クライアントに表示する画面を指定します。


クライアントに表示したい画面の「Viewインスタンス」を受け渡すことにより、遷移先の指定が可能ということが、何よりも直感的で分かり易いと思います。
この、遷移先指定が「直感的」かつ「タイプセーフ」である事が、特徴の1つでもあります。


5.executeメソッド

   /** executeボタンが押下された時に呼び出されるメソッド */
   public void execute(Add add) {
      // 画面の入力値をビュークラス(Add)にセットします。
      request.copy(add);
      // 入力値の検証を行います。
      add.validate();
      // 入力値を加算し、合計をAdd.totalにセットします。
      add.total = Integer.parseInt(add.value1) + Integer.parseInt(add.value2);
      // クライアントに表示する画面(HTML)に対応するビュークラスをセットします。
      response.setPage(add);
   }
executeメソッドは、足し算画面(Add.html)の「計算」ボタンが押された時に、呼び出されるメソッドです。
呼び出すクラスは、要求のあった「画面(HTML)名」に対応するコントローラー・クラスです。
呼び出すメソッドは、押されたボタンの「name属性」と同名のメソッドです。
シグニチャは、画面(HTML)のViewクラス(Add.java)が受け渡されます。

それでは、メソッド内部の説明を致します。


      // 画面の入力値をビュークラス(Add)にセットします。
      request.copy(add);
上記ソースは、足し算画面(Add.html)で、入力された値をViewクラス(Add.java)にセットします。
Viewクラスへの入力値の自動セットはフレームワークでは行いません。
その理由は、ボタン毎に入力値のセットの切り替えを、設定ファイルやアノテーションで記述すると煩雑になり、ソースの可読性が下がるためです。



但し、画面入力値のセットする処理をマニュアルで記述するのは無駄であり、ソースも冗長になることから、EzRequestの「copyメソッド」のシグニチャにViewクラスを受け渡すと自動で入力値をセットする機能があります。

      // 入力値の検証を行います。
      add.validate();
上記ソースは、画面入力値の妥当性の検証を行っています。
検証エラーが発生した場合は、後続処理を中断し、「エラーメッセージ」を設定された画面(HTML)に表示します。


Viewクラスの「validateメソッド」は、フレームワークから呼びだしません。
理由は、処理の流れを「Controllerクラス」を参照するだけで、理解できるようにするためです。
ボタン毎のバリデーションの切り替えを、設定ファイルやアノテーションで記述すると煩雑になり、ソースの可読性が下がるためです。

      // 入力値を加算し、合計をAdd.totalにセットします。
      add.total = Integer.parseInt(add.value1) + Integer.parseInt(add.value2);
上記ソースは、画面(HTML)で入力されたvalue1とvalue2を加算し、出力項目用プロパティtotalに結果をセットしています。

      // クライアントに表示する画面(HTML)に対応するビュークラスをセットします。
      response.setPage(add);
上記ソースは、画面の遷移先を指定しています。今回の例では、入力画面と同じAdd.htmlを指定した事になります。遷移したい画面(HTML)に対応するViewクラスを、responseのsetPageメソッドに設定することで、画面の遷移先を指定することが出来るのです。このクールさが、EzSetvletの持ち味です。


FW専用タグの説明
EzServletは、VIEWをHTMLテンプレートで開発します。
HTMLテンプレートのメリットは、JSPの知識が不要となるだけではなく、モックHTMLを開発に利用できることが挙げられます。
また、VIEWにロジックを含まない(出来ない)ため、各種ソースの見通しが良くなります。
HTMLを、動的な画面にするための(6個の)専用タグの説明をします。


1.label(表示項目)タグ


 モックHTMLで表示するダミー値
専用タグの「name属性」をキーに、プロパティファイルから表示する値を取得するタグです。プロパティファイルからの値の取得と値の置き換えは、FWで行います。


2.out(出力項目)タグ

 モックHTMLで表示するダミー値
Viewクラスから、専用タグの「name属性」と同名のプロパティの値を表示する値を取得するタグです。


3.boolean(表示・非表示)タグ

 trueの場合に表示する内容
 falseの場合に表示する内容
Viewクラスの、専用タグの「name属性」と同名のプロパティ(boolean)の値で「表示・非表示」を切り替えるタグです。


4.child(子クラス)タグ

 ネストするHTML
ネストする画面(*1)を作成する際に利用するタグです。
専用タグの「name属性」が、子Viewクラスの名称になります。
親Viewクラスのインナークラスとして子Viewクラスを定義します。
親Viewクラスには、子Viewクラスを格納するListプロパティを持つ事になります。
子Viewクラス格納リストの名前は、子Viewクラスのキャメル記法+Listになります。


(*1)ネストする画面とは、親子(孫…)関係にある画面のことを指す。例えば、顧客情報と受注情報
  を1画面で表示する場合等がネストする画面になる。顧客情報:受注情報=1対n



5.include(インクルード)タグ

 includeするHTML名">モック用ダミーHTML
専用タグの「name属性」のHTMLを、自HTMLにインクルードします。


6.remove(実行時除外)タグ

 モック用ダミーHTML
専用タグで囲まれたダミーHTMLを実行時には除外(表示しない)タグです。




なんか専用タグの名称は、完全に「Wicket」の影響を受けてる気がする。。。(^^;)



FW専用クラスの説明


つづく…