Velocity を内部で使っていて、テンプレートモデルで、ページを作成します。

ここでは、Click の覚書きをしておきます。あくまで個人用なので、あてにしないようにお願いします。間違い等発見された方は、ご連絡いただけると助かります。

使用バージョン
  • version Click 0.1.8

Clickはドキュメントがしっかりできているので、ドキュメントを読むのが一番です

参考

覚書き

Clickとは

Clickはコンポーネント&ページ指向のイベントドリブンアーキテクチャを持つ、J2EE Webアプリケーションフレームワークです。シンプルなアーキテクチャになっていて、JSFよりも直感的でわかりやすいプログラミングができます。

Clickには大きく2つのコンポーネントが用意されています。一つは、Pageです。これは、その名の通り、一つのページを表すコンポーネントです。もう一つは、Controlで、これは、ページの要素(例えばリンクやボタンなど)を表します。

ページは複数のコントロールを持つことができます。ページのレンダリング時には、これらのコントロールをVelocityテンプレートと照らし合わせてレンダリングを行います。コントロールに付けた名前が、Velocityテンプレート中で使えるモデルの名前になります。

Clickの本体は、net.sf.click.ClickServlet です。このクラスか、このクラスを継承したサブクラスをサーブレットとして使います。

Clickの慣習で、マッピングパターンは、*.htm にするようです。

<servlet> 
  <servlet-name>click-servlet</servlet-name> 
  <servlet-class>net.sf.click.ClickServlet</servlet-class> 
  <load-on-startup>0</load-on-startup> 
</servlet> 
 
<servlet-mapping> 
  <servlet-name>click-servlet</servlet-name> 
  <url-pattern>*.htm</url-pattern> 
</servlet-mapping>

net.sf.click.Page

一ページを表すクラスです。開発者はこのクラスを継承してページクラスを作成します。ページには、複数のControlを持たせることができます。

ページには、次の2つの種類のメソッドを定義することができます。

  1. ページのライフサイクルに関するイベントハンドリングメソッド
  2. コントロールのイベントリスナメソッド

ページのライフサイクルに関するイベントハンドリングメソッド

ページは、あらかじめ決められたイベントハンドリングポイントが用意されています。以下のメソッドをオーバーライドすることで、イベントハンドリングを実装できます。

onInit()
サーブレットがリクエストを受けて、ページをロードしたときに呼び出されます
onSecurityCheck()
onInit()の後に呼び出されます。アクセス制御等のセキュリティ確認を行える場所です
onGet()
Getメソッドのリクエストの場合に呼び出されます。onSecurityCheck()の後に呼び出されます
onPost()
Postメソッドのリクエストの場合に呼び出されます。onSecurityCheck()の後に呼び出されます
onDestroy()
ページが廃棄されるときに呼び出されます

これらのメソッドは、ページのイベントシーケンスにしたがって呼び出されます。

参考

コントロールのイベントリスナメソッド

リスナメソッドをコントロールに登録することで、コントロールに対するイベントが発生した場合にハンドリング処理ができるようになります。イベントリスナメソッドは、次の2つのルールを満たさなければなりません。

  1. 引数は無し
  2. boolean もしくは java.lang.Boolean を戻り値で返す

イベントリスナメソッドの戻り値は、次のような意味を持ちます。

true の場合

続けて他のコントロールの onProcess() メソッドが呼び出されます。その後、ページのonGet() メソッド または、 onPost() メソッドが呼び出されます。

falseの場合

他のコントロールの処理は実行されません。また、ページの onGet()、onPost() メソッドも呼び出されません。そのままページの遷移処理、またはレンダリング処理に入ります。

上記の動作から分かることは、イベントハンドリング処理で、ページの遷移等を行う場合は、戻り値を false にする必要があるということです。ページ遷移を伴わないイベントハンドリング処理の場合は、true を返すようにします。

サーブレットAPIを使うには

Clickには、コンテキスト(net.sf.click.Context)と言うものがあります。ClickServletは、リクエストを受けると、要求されたページとコンテキストを結び付けます。ページ内のメソッドからは、このコンテキストを通して、通常のServletAPIを使用することができます。コンテキストを取得するには、Page#getContext() メソッドを呼び出します。

コントロールはデフォルトコンストラクタの中で追加する

ページが要求されると、ClickServletは、ページのインスタンス化を行います。このとき、引数のないデフォルトコンストラクタが呼び出されます。 ※ ただし、この動作はClickServletのデフォルト実装によるもので、サブクラスでは、インスタンス化の方法をオーバーライドすることができます。

インスタンス化されたページは、そのままページの処理シーケンスに突入します。そのため、インスタンス化された時点で静的なコントロールは new しておくことが望ましいです。もちろん、処理シーケンス中で、動的にコントロールを作成することも可能です。

public class Login extends Page {
  private Form loginForm = new Form("loginForm");
  public Login() {
    this.loginForm.add(new TextField("userName", "ユーザ名", true));
    this.loginForm.add(new PasswordField("password", true));
    this.loginForm.add(new Submit("login", " ログイン ", this, "onLoginClicked"));
    super.addControl(this.loginForm);
  }
 
  /* その他の実装 */
}

コントロールを動的に追加するには、onGet() メソッドか onPost() メソッド中で実装すると良いと思います。

@Override
public void onGet() {
  this.onHandleRequest();
}
 
@Override
public void onPost() {        
  this.onHandleRequest();
}
 
protected void onHandleRequest() {
  String userName = 
        super.getContext().getRequestParameter("userName");
  if ("admin".equals(userName)) {
    super.addControl(new Label("menu", "管理者メニュー"));
  } else {
    super.addControl(new Label("menu", "一般メニュー"));
  }
}

モデルを画面に表示する

addModel メソッドを呼びだして、名前を指定してモデルを登録します。ここで指定した名前で Velocityテンプレートから参照することができます。

net.sf.click.Control

ページを構成するコンポーネント(例えば、フォームやリンク、ボタン、テキストボックスなど)です。コントロールには次のような大分類に分けられます。

ActionLink
リンクを表します。リスナを登録することで、コールバック(イベント)を受け取ることができます
Field
フォームと一緒に使われる入力フィールドです。フィールドは、自分自身をバリデーションします
Form
入力フォームです。自分自身とフィールドのバリデーション機能を持ちます。また、フォームは、独自のレイアウトを持ちます

ActionLink

アンカーを持つリンクです。

リスナを登録することで、リンクがクリックされたときのイベントをハンドリングできます。

参考

Field

フォームの入力フィールドです。様々な種類があります。フィールドは、自分自身でバリデーションを行うことができます。必須入力、最大・最小文字長等のチェックを行います。

参考

Form

フォームコントロールです。フォームに入力フィールドを追加して使います。フォームは、レイアウトフォーマットを持っています。フィールドの数等によってフォームのレイアウトが自動で設定されます。また、フォームには、入力値をオブジェクトに変換する役割もあります。

参考

ページ遷移の仕組み

Click には3つのページ遷移の方法があります。

  • Forward
  • Redirect
  • テンプレート置き換え

Forward

サーブレットの request.getRequestDispatcher を使ってページを遷移します。Fowardさせるには、Pageクラスのイベントハンドラで、setFoward() を呼び出します。

@Override
public void onPost() {
  super.setForward("login.htm");
}

setForward() に与えるページパスは、パスの先頭に “/” 先頭にを含めません。フォワード先にパラメータを送りたい場合は、getContext().setRequestAttribute() を呼び出します。

参考

getContext().createPage() を呼び出して、遷移先のページを作成するというやり方もあります。この例も、上の「参考」に例があります。

Redirect

サーブレットの response.sendRedirect() を呼び出して、ページを遷移します。リダイレクトしたい場合は、Page#setRedirect() を呼び出して、リダイレクト先のパスを設定します。リダイレクト先のパスの先頭に “/” を付けると、コンテキストルートからのパスという意味になります。(つまり、パスの先頭にコンテキスト名が付与されます)

テンプレート置き換え

setForward() も setRedirect() もされていない場合は、Velocityテンプレートをレンダリングします。使われるVelocityテンプレートは、Page#getTemplate() の戻り値になります。これは、デフォルトで、パス名と同じファイルになります。getTemplate() をオーバーライドして、テンプレート名を変えることで、出力を変えることができます。

ClickをSpring Frameworkと一緒に使う

Clickを Spring Framework と一緒に使う方法です。Clickをダウンロードするとついてくる click-extras.jar を使います。このライブラリに含まれている net.sf.click.extras.spring.SpringClickServlet を ClickServlet の代わりに使います。そして、Spring Framework のアプリケーションコンテキスト定義(applicationContext.xml)のパスを与えてやります。

<servlet>
   <servlet-name>click-servlet</servlet-name>
   <servlet-class>net.sf.click.extras.spring.SpringClickServlet</servlet-class>
   <init-param>
     <param-name>spring-path</param-name>
     <param-value>/WEB-INF/applicationContext.xml</param-value>
   </init-param>
   <load-on-startup>0</load-on-startup>
</servlet>