Apache Click について学ぶ

重たいフレームワークが不要な軽量モデルを使用して、素早く Web アプリケーションを作成する

Apache Click について学びましょう。Apache Click は MVC (Model-View-Controller) パターンや JSP (JavaServer Pages) を使わずに Web アプリケーションを作成することができる Java EE (Java™ Platform, Enterprise Edition) Web アプリケーション・フレームワークです。この記事では、単純な Web ページを表示する例と、別の Web ページに表示されるデータを送信する Web フォームを作成する例を説明します。

Nathan A. Good, Senior Consultant and Freelance Developer, Enterprise Frameworks

Nathan GoodNathan A. Good はミネソタ州の Twin Cities エリアに住んでいます。彼はプロとしてソフトウェア開発やソフトウェア・アーキテクチャー、システム管理などを行っています。彼はソフトウェアを書いている時以外は、PC やサーバーを構築したり、新しい技術について資料を読んだり、そうした技術に取り組んだり、彼の友人達をオープソース・ソフトウェアに移行させようとしたりしています。彼は数多くの本や記事を執筆、あるいは共同で執筆しており、その中には『Professional Red Hat Enterprise Linux 3』や『Regular Expression Recipes: A Problem-Solution Approach』、『Foundations of PEAR: Rapid PHP Development』などがあります。



2010年 1月 26日

この記事で説明する例を試すには、Eclipse と Web アプリケーション・サーバーをインストールしておく必要があります。この記事の例では Web アプリケーション・サーバーとして Tomcat 6.0 を使用しますが、他の Web アプリケーション・サーバー (例えば WebSphere® Application Server Community Edition や Jetty、あるいは古いバージョンの Tomcat) でも同じように動作するはずです。まだ Web アプリケーション・サーバーをインストールしていない場合には、「参考文献」を参照して、Apache Tomcat 6.0 または WebSphere Application Server Community Edition をダウンロードしてインストールしてください。

Apache Click の概要

Apache Click は Java Web アプリケーションを素早く作成できるようにしてくれる Web アプリケーション・フレームワークです。Apache Click の目的は、JSP や MVC フレームワークを使用せずに Web アプリケーションを作成する手段を提供することです (JSP や MVC フレームワークは一部の Web アプリケーションには重たすぎる場合があります)。Apache Click は Apache ライセンスの下でライセンスされています (「参考文献」を参照)。

Apache Click は重たいフレームワークの代わりに、HTML テンプレートと POJO (Plain Old Java Object) を使用します。HTML テンプレートは Apache Velocity テンプレート・エンジンによって処理されます (Apache Velocity についての詳細は「参考文献」を参照してください)。Apache Velocity テンプレート・エンジンは、特殊なタグを使わずに、テンプレートを可能な限り標準的な HTML に近づけることを目標にしています。Velocity テンプレートの構文を学ぶ際の学習曲線は至ってなだらかであり、Web 開発者は従来の HTML のスキルを活用することができます。

POJO は Apache Click のディストリビューションに提供されている基底クラスを継承します。Apache Click には Page クラスとコンポーネント・クラスが含まれており、これらのサブクラスを作成することで各ページの処理をするコードを実装することができます。これらのコンポーネントには、そのまま何も手を加えずに使用できる関数が用意されており、それらの関数を使用することで、HTML のコントロールを作成したり、イベントに応答したりすることができます。

また Apache Click には、モック・テストのための API も含まれています。この API を使用することで、より適切なユニット・テストや、継続的インテグレーションによるビルド、そして TDD (Test-Driven Development: テスト駆動開発) を行うことができます。Mock API については「参考文献」を参照してください。


Apache Click のコンポーネントとイベント処理

org.apache.click.Page クラスは各ページ・コンポーネントの基底クラスです。Page 基底クラスには、ページが初期化された時にイベントを処理するメソッド (onInit()) や、ページが描画された時にイベントを処理するメソッド (onRender())、そしてページのセキュリティーを処理するメソッド (onSecurityCheck()) が含まれています。Page クラスを継承するクラスの中で、これらのメソッドをオーバーライドし、カスタムの関数を提供することもできます。また Page クラスを継承する各クラスには、ページ上のイベントを処理するメソッドが含まれる場合もあります。

ステートフルなページを作成するためには、java.io.Serializable インターフェースを実装し、Page 基底クラスの setStateful() メソッドをコンストラクターの中で呼び出します (リスト 1)。

リスト 1. ステートフルなプロパティーをコンストラクターの中で設定する
    public WelcomePage() {
        setStateful(true);
    }

Apache Click には、HTML 要素に対応するコントロール・コンポーネントがいくつか付属しています。これらのコントロール・コンポーネントを使用すると、動的にコントロールを追加することで、プログラムによってフォームのセットアップをすることができます。またこれらのコントロール・コンポーネントを使用すると、HTML コントロール・データを Java コードで取得したり設定したりすることもできます。

フィールド・コントロール (TextField, Select など) の setEventListener() メソッドを使用すると、フィールドへの入力が有効であればフォームの処理の際に実行される (Page クラスを継承したクラスの) メソッドを定義することができます。

ボタンやリンクによってイベントを処理することもできます。リスト 2 に示す宣言を使用すると、フォーム上に新しい送信ボタンを作成し、そのボタンを Page クラスのメソッドにリンクさせることができます。

リスト 2. onClick イベント・ハンドラーを使用して送信ボタンを作成するonClick event handler
Submit submitButton = new Submit("Submit Me", this, "onClick");

ボタンがクリックされると、そのイベントはカスタム Page クラスの onClick() メソッドに渡されます。onClick() メソッドの中にあるコードは、データベースにデータを保存するコードや新しいページを表示するコードを含め、すべてのコードが実行されます。

この API についての詳細は「参考文献」を参照してください。


Apache Click のテンプレート

Apache Click はデフォルトで、Apache Velocity テンプレート・エンジンを使います。このテンプレート・エンジンは、いくつかのデフォルトのマッピング・ルールを使用して、アプリケーションの中で Page クラスを継承するクラスとテンプレートが自動的に対応付けられます。例えば、HelloPage というページ・クラスは Web プロジェクトの hello.html という HTML ファイルに自動的にマッピングされます。HelloWorldPage というページは、helloWorld.html または hello-world.htmlというページに自動的にマッピングされます。

デフォルトのページ・マッピングを使いたくない場合には、click.xml ファイルを変更して独自のカスタム・マッピングを追加することで、マッピングを変更することができます。

Velocity のページ・マッピングを使用しないだけでなく、テンプレート・エンジンとして Velocity を使用しないようにすることもできます。Apache Click では JSP を使って描画することもできるので、既存の JSP を使用することもできます。


Apache Click をダウンロードする

Apache Click の Web サイトから Apache Click をダウンロードします (「参考文献」を参照)。ダウンロードしたら、覚えやすい場所に圧縮ファイル (.zip ファイル) を解凍します。

Apache Click に付属しているサンプルを見たい場合には、dist フォルダーから click-examples.war ファイルを Web アプリケーション・サーバーにデプロイすることができます。これらのサンプルには、テーブルの作成やコントロールの使い方、テンプレートの使い方など、数多くの多様なシナリオが含まれています。

ダウンロードとファイルの解凍が終わると、Apache Click ライブラリーを含む Web アプリケーションを作成する準備が整ったことになります。


Apache Click をインポートする

Apache Click をインストールするには、必要な JAR (Java Archive) ファイルを Web プロジェクトに配置します。Web プロジェクトに Apache Click を含めたら、このプロジェクトを Web アプリケーション・サーバーにデプロイします。

Apache Click を使用する Web アプリケーションを Eclipse を使って作成するためには、以下のステップに従います。

  1. Eclipse のメニューから「New (新規)」 > 「Other (その他)」の順に選択します。
  2. 表示された「Select a Wizard (ウィザードを選択)」画面から「Web / Dynamic Web Project (Web / 動的 Web プロジェクト)」を選択し、「Next (次へ)」をクリックします。
  3. 「Project Name (プロジェクト名)」に名前を入力します (例えば「MyFirstClick」など)。
  4. 「Target Runtime」ではいずれかを選択します (「Apache Tomcat v6.0」など)。Eclipse でランタイムを構成する方法については「参考文献」を参照してください。
  5. 「Finish (完了)」をクリックします。他のフィールドの値はデフォルトのままにしておきます。

これらのステップを完了すると、Eclipse の中に新しい空の Web プロジェクトが作成されているはずです (図 1 を参照)。

図 1. 空の Web プロジェクト
このスクリーン・ショットには、空の Web プロジェクトのディレクトリーが表示されています。

これで Apache Click ライブラリーをインポートすることができます。以下のステップでライブラリーをインポートします。

  1. 「File (ファイル)」 > 「Import (インポート)」の順にクリックします。
  2. リストから「General / File System (一般 / ファイル・システム)」を選択し、「Next (次へ)」をクリックします。
  3. Apache Click のファイルを展開したディレクトリーまでナビゲートし、「dist」ディレクトリーを選択します。
  4. フィアイルのリストから、「click-{version}.jar」ファイルと「click-{version}-extras.jar」ファイルを選択します (図 2)。
    図 2. JAR ファイルをインポートする
    このウィンドウでは、「click-2.0.1-incubating.jar」と「click-extras-2.0.1-incubating.jar」が選択されています。
  5. 「Into folder (宛先フォルダー)」フィールドで「WebContent/WEB-INF/lib」フォルダーが選択されていることを確認した後、「Finish (完了)」をクリックします。

これで WEB-INF ディレクトリーに JAR ファイルを配置できたので、ClickServlet を含むように Web アプリケーションの web.xml ファイルを変更します (ClickServlet は Apache Click がイベントをディスパッチするために唯一使用するサーブレットです)。web.xml ファイルにこのサーブレットを構成したら、この記事のサンプルを使用する上では、これ以上 web.xml ファイルを変更する必要はありません。この web.xml の内容をリスト 3 に示します。

リスト 3. web.xml ファイル
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee" 
		xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
		http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    id="WebApp_ID" version="2.5">
    <display-name>MyFirstClick</display-name>

    <servlet>
        <servlet-name>ClickServlet</servlet-name>
        <servlet-class>org.apache.click.ClickServlet</servlet-class>
        <load-on-startup>0</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>ClickServlet</servlet-name>
        <url-pattern>*.html</url-pattern>
    </servlet-mapping>

    <welcome-file-list>
        <welcome-file>welcome.html</welcome-file>
    </welcome-file-list>

</web-app>

今度は、ページのクラスを入れるためのパッケージを作成します (例えば com.example.myfirstclick.pages など)。このパッケージを作成したら、Web プロジェクトの WEB-INF フォルダーの中に click.xml という新しいファイルを作成します。そして、今作成したパッケージの名前を click.xml ファイルの中に含めます (リスト 4)。

リスト 4. click.xml ファイル
<?xml version="1.0" encoding="UTF-8"?>
<click-app>
    <pages package="com.example.myfirstclick.pages" />
</click-app>

サンプル・アプリケーションを作成する

これでプロジェクトがセットアップできたので、Apache Click に含まれているクラスを継承するクラスの作成を始めることができます。最初のクラスは、すべてのページ・コンポーネントの基底クラスである Page クラスを継承します。上で作成したパッケージの中に新しいクラスを作成します。そのためには、「File (ファイル)」 > 「New (新規)」 > 「Other (その他)」の順に選択するのに続いて「Java / Class (Java / クラス)」を選択します。「Superclass (スーパークラス)」として必ず「org.apache.click.Page」と入力します。

この新しいクラスにリスト 5 の内容を追加します。

リスト 5. WelcomePage クラス
package com.example.myfirstclick.pages;

import org.apache.click.Page;

public class WelcomePage extends Page {

    // Initialize the value to something
    protected String theMessage = "Welcome!";

    public WelcomePage() {
        // Add the value to the map ("message" = "$message")
        addModel("message", theMessage);
    }
}

これで WelcomePage クラスを作成できたので、ブラウザーに対する出力のテンプレートとなる HTML ページを作成する必要があります。Apache Click のデフォルトのテンプレート・エンジンは Apache Velocity なので、この HTML ファイルは通常の静的な HTML ページと似たものになります。

Webプロジェクトの「WebContent」フォルダーの中に、welcome.html という新しい HTML ページを作成し、リスト 6 の内容を追加します。

リスト 6. welcome.html ファイル
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>MyFirstClick Welcome</title>
</head>
<body>
<p>$message</p>
</body>
</html>

新しい HTML ファイルの中の $message に注意してください。この変数は、ページが生成されるとVelocity テンプレート・エンジンによって置き換えられます。ClickServletWelcomePage クラスを welcome.html ファイルと対応付けます。WelcomePage クラスは、このクラスのメッセージ・フィールドを 1 つの値 (Welcome!) に初期化し、コンストラクターの中でその値をモデルに追加します。そのためにコンストラクターでは、addModel() メソッドに引数として変数の名前 (message$message にマッピングされます) とその値 (theMessage フィールド) を渡して実行しています。これにより、メッセージ・フィールドに割り当てられた値がブラウザーに表示されます。


サンプル・アプリケーションを実行する

これでファイルを作成できたので、このアプリケーションを試すことができます。そのためにはファイル群を WAR (Web Archive) として Tomcat の webapps フォルダーにエクスポートします。これを最も容易に行うためには、Eclipse を使って以下のステップを実行します。

  1. この MyFirstClick プロジェクトをクリックし、「File (ファイル)」 > 「Export (エクスポート)」の順に選択します。
  2. 「Web / WAR file (Web / WAR ファイル)」をクリックし、「Next (次へ)」をクリックします。
  3. 「Destination (宛先)」フィールドで Tomcat の webapps フォルダーを指定します。
  4. 「Overwrite existing files (既存ファイルを上書き)」が選択されていることを確認し、「Finish (完了)」をクリックします (図 3)。
    図 3. プロジェクトを WAR としてエクスポートする
    このウィンドウには MyFirstClick が Web プロジェクトとして表示されています。

WAR ファイルを Tomcat の webapps ディレクトリーにエクスポートすると、ブラウザーで http://localhost:8080/MyFirstClick/welcome.html を指定すれば新しいページを表示することができます (Web アプリケーション・サーバーが別のポートにバインドされている場合や、Web アプリケーションに対して別の名前を選択した場合には、この URL とは異なるかもしれません)。

このサンプル・アプリケーションを実験するために、WelcomePage のメッセージ・フィールドの値を変更し、再度このサンプルを Web アプリケーション・サーバーにデプロイします。値が変更されることを確認できると、より動的なサンプルを試すことができます。


フォームを作成する

単純なウェルカム・ページを作成できたので、今度はもう少し複雑なことをします。動的な Web サイトが読み取り専用データのみで構成されることはほとんどありません。動的な Web サイトの大部分では、どこかの時点でユーザー入力を要求し、そのユーザー入力を使って何らかのことをします。フォームはその典型的な例であり、フォームが入力を受け付けると、その入力を表示した別の Web ページをユーザーに表示します。

このサンプル・アプリケーションを表示するために、Page クラスを継承する別のクラスを作成します。この新しいクラスに InputPage という名前を付けます (リスト 7)。

リスト 7. InputPage クラス
package com.example.myfirstclick.pages;

import org.apache.click.Page;
import org.apache.click.control.Form;
import org.apache.click.control.Submit;
import org.apache.click.control.TextField;

public class InputPage extends Page {

    public Form form = new Form();

    private TextField nameField;

    public InputPage() {

        form.setLabelsPosition(Form.POSITION_TOP);

        nameField = new TextField("Enter your name");

        form.add(nameField);
        form.add(new Submit("Submit", this, "onSubmitClick"));

    }
    
    public boolean onSubmitClick()
    {
        SayHelloPage nextPage = (SayHelloPage)getContext().createPage("/sayHello.html");
        nextPage.setName(nameField.getValue());
        
        setForward(nextPage);
        
        return false;
    }

}

この新しいクラスはコンストラクターの中で Form オブジェクトを設定し、このオブジェクトに入力用のフィールドを追加します。次に InputPage クラスは、ハンドラー (onSubmitClick() メソッド) を持つ HTML の送信ボタンを追加します。このハンドラーは送信ボタンが押されると実行されます。そのため、InputPage クラスはハンドラーの中で次のページを設定する必要があります。次のページ (つまり SayHelloPage) が追加されるまで、コードはコンパイルされません。

今度は、Web プロジェクトの WebContent フォルダーの中に新しい HTML ファイルを作成し、input.html という名前を付けます。このページに $form 変数を配置します ($form 変数は InputPage クラスのフォーム・フィールドからの HTML 出力で置き換えられます)。この作業によって、input.html ファイルはリスト 8 のようになるはずです。

リスト 8. input.html ファイル
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>MyFirstClick Input Sample</title>
</head>
<body>
$form
</body>
</html>

今度は、入力した内容を表示するページを SayHelloPage という別のクラスとして追加し、このクラスも org.apache.click.Page を継承するようにします。この新しいクラスはリスト 9 のようになるはずです。

リスト 9. SayHelloPage クラス
package com.example.myfirstclick.pages;

import org.apache.click.Page;

public class SayHelloPage extends Page {

    private String name;
    
    @Override
    public void onInit()
    {
        super.onInit();
        
        if (name != null)
        {
            addModel("name", name);
        }

    }
    
    public void setName(String name) {
        this.name = name;
    }    
    
}

このクラスは Page 基底クラスの onInit() メソッドをオーバーライドし、ページ上に表示される値を設定します。addModel() メソッドを使ってモデルに追加するすべての値に対し、ヌル・チェックをすることを忘れないでください。もしヌル値を追加しようとすると、IllegalArgumentException がスローされます。このようにすることで、開発者は必然的に値がヌルの場合にもページを適切に表示するコードを作成するようになります。

SayHelloPage クラスの name フィールドは、setName() という public なセッターを使って公開されています。このアクセサーは、InputPage クラスの onSubmitClick() イベント・ハンドラー・メソッドの中で SayHelloPage の新しいインスタンスが取得されるとコールバックされます。

「No path configured... (パスが構成されていません)」というエラー

私がこのコードを最初に実行した際、ClickServlet から「No path configured for Page class: com.example.myfirstclick.pages.SayHelloPage (Page クラスのパスが構成されていません: com.example.myfirstclick.pages.SayHelloPage)」というエラーが発生しました。これは、私が click.xml の中でページを構成せずに SayHelloPage.classcreatePage() に渡していたためです。SayHelloPage.class を渡すのではなく、/sayHello.html を渡すように変更したところ、適切に動作するようになりました。これは、Apache Click はデフォルトで .jsp と .htm という拡張子のファイルにマッピングされますが、私はマッピングされるファイルの拡張子として .html を設定していたためです。

onSubmitClick() メソッドは nameField コントロール (nameField.getValue()) から得られる値を使ってページの名前を設定し、続いて setForward() メソッドを使ってそのページが表示されるようにします。その結果、SayHelloPage の name フィールドには入力ボックスの値が入れられ、その値は $name に格納されます。

今度は、$name 変数を含む sayHello.html という HTML ファイルを追加します。sayHello.html の内容を示したものがリスト 10 です。

リスト 10. sayHello.html ページ
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Results</title>
</head>
<body>
<p>Hello, $name!</p>
</body>
</html>

このサンプルを実行するためには、Web ブラウザーで http://localhost:8080/MyFirstClick/input.html を指定します。テキスト・ボックスに値を入力し、Submit を押すと、入力された値がブラウザーに表示されます。


まとめ

Apache Click を利用すると、重たいフレームワークを使用せずに軽量のモデルを使用して、素早く Web アプリケーションを作成することができます。Apache Click は単純なため、ユーザーは独自のオブジェクト指向プログラミングのプラクティスやパターンを使用することができます。また、デフォルトのテンプレート・エンジンである Velocity を使用することによって、カスタム・タグを必要とすることなく、より HTML 仕様に忠実な HTML コードを作成することができます。

Apache Click のコンポーネントとイベント・モデルを使用すると、わずかな学習期間で HTML コントロールを作成してイベントを処理することができるようになります。

参考文献

学ぶために

製品や技術を入手するために

議論するために

コメント

developerWorks: サイン・イン

必須フィールドは(*)で示されます。


IBM ID が必要ですか?
IBM IDをお忘れですか?


パスワードをお忘れですか?
パスワードの変更

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


お客様が developerWorks に初めてサインインすると、お客様のプロフィールが作成されます。会社名を非表示とする選択を行わない限り、プロフィール内の情報(名前、国/地域や会社名)は公開され、投稿するコンテンツと一緒に表示されますが、いつでもこれらの情報を更新できます。

送信されたすべての情報は安全です。

ディスプレイ・ネームを選択してください



developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

必須フィールドは(*)で示されます。

3文字から31文字の範囲で指定し

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


送信されたすべての情報は安全です。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Web development, Open source, Java technology
ArticleID=468824
ArticleTitle=Apache Click について学ぶ
publish-date=01262010