Echo Web Frameworkとは
「Echo Web Framework 」( 以下、Echo)は、Ajaxに対応したオープンソースのWebアプリケーション・フレームワークです。Webアプリケーション開発向けのフレームワークは無数に存在しますが、Echoがそれらのフレームワークと大きく異なるのは、サーバサイドのJavaコードのみによるアプリケーション開発と、クライアントサイドのJavaScriptのみによるアプリケーション開発の両方を同時にサポートしている点です。
Javaコードによるアプリケーション開発では、AWT/Swingに似たコンポーネント・ベースのプログラミングモデルによってUIを作成します。クライアントとサーバとの通信にはServletの仕組みが利用されます。すなわち、UIを構成するJavaコードはServletプログラムとして動作し、クライアントからの接続要求があると、自動でJavaScriptを利用したHTMLページを構築して返す仕組みになっています。したがって、開発者が直接HTMLやJavaScriptのコードを記述する必要はありません。
一方、JavaScriptによるアプリケーション開発では、HTMLで用意されたタグ・コンポーネントではなく、Echo独自のJavaScriptオブジェクトによるコンポーネントを用いてUIを作成します。したがってコードのほとんどはJavaScriptのみで構成され、HTMLは最小限、サーバ側のプログラムに至っては一切記述する必要がありません。コンポーネントモデルは、サーバサイドと同様にJavaのAWT/Swingに似たものになっているため、JavaのGUIアプリケーションと同じ感覚でUIを構築することが可能です。
Javaのみ、またはJavaScriptのみでの開発を可能にするフレームワークは他にもありますが、Echoの場合は、その両方を同時にサポートしており、双方で似たプログラミング・モデルを採用しているという点がきわめて特徴的です。今回は、まずサーバサイド、すなわちJavaコードによるWebアプリケーションの開発方法を紹介したいと思います。
JavaコードによるWebアプリケーションの作成
本稿執筆時点では、Echoの次期バージョンとなるEcho3のRC1(リリース候補1)が公開されているので、今回はこれを利用します。Echo 3 RC1はこのページ よりダウンロードできます。ダウンロードしたファイルを解凍すると、JavaLibrariesフォルダに「Echo3_App.jar」と「Echo3_WebContainer.jar」という2つのjarファイルがあります。この2つを作成するWebアプリケーションプロジェクトのクラスパスに追加すれば、Echo3を使うことができます。
Echoのサーバサイド・アプリケーションは、ApplicationInstanceクラスを継承して作成します。ApplicationInstanceはabstractクラスであり、初期化用のinit()というメソッドがひとつ定義されているので、これをオーバーライドしてアプリケーションの中身を作っていきます。UIの構成にはAWT/Swingに似たコンポーネントモデルが採用されており、まずベースとなるWindowクラスがあって、そこにContentPaneをはじめとする各種Paneや、LabelやButtonなどのコンポーネントをサブコンポーネントとして追加していきます。たとえば、画面に「Hello, Echo3!」と表示するプログラムは次のようになります。
package jp.gihyo.toolbox.echo;
import nextapp.echo.app.*;
public class HelloEcho extends ApplicationInstance {
@Override
public Window init() {
Window window = new Window();
window.setTitle("Echo Framworkのサンプル");
// ContentPaneの作成
ContentPane contentPane = new ContentPane();
contentPane.setInsets(new Insets(new Extent(20)));
window.setContent(contentPane);
// フォントを指定してラベルを配置
Label label = new Label("Hello, Echo3!");
Font font = new Font(Font.SANS_SERIF, Font.PLAIN, new Extent(36));
label.setFont(font);
contentPane.add(label);
return window;
}
}
Insetsはコンポーネントの周り(内側)の余白を表すクラスです。Extentは直線距離を表すためのクラスで、コンポーネントの縦/横サイズや、コンポーネント間の距離の設定などに利用します。各クラスの詳細は、APIドキュメント を参照してください。
前述のように、Echoのサーバサイド・プログラムはServletの一種として動作します。そのため、起点となるためのWebContainerServletを継承したクラスを作成する必要があります。WebContainerServletにはApplicationInstanceオブジェクトを返すnewApplicationInstance()メソッドが定義されているので、次に示すように、これをオーバーライドしてHelloEchoクラスのインスタンスを返すようにします。
package jp.gihyo.toolbox.echo;
import javax.servlet.annotation.WebServlet;
import nextapp.echo.app.ApplicationInstance;
import nextapp.echo.webcontainer.WebContainerServlet;
@WebServlet("/hello")
public class HelloEchoServlet extends WebContainerServlet {
@Override
public ApplicationInstance newApplicationInstance() {
return new HelloEcho();
}
}
ここでは、web.xmlは使わずに@WebServletアノテーションを利用してServlet名の設定を行っています。プロジェクトをサーバにデプロイしたら、Webブラウザから@WebServletで設定した"/hello"にアクセスします。URLは、たとえば「http://localhost:8080/EchoSample/hello」のようになります。正しくデプロイできていれば図1のように表示されるはずです。
図1 EchoのJava APIで作成したWebページの例
入力フォームを利用する
続いてテキストフィールドやボタンなどによる入力フォームを利用してみましょう。テキストフィールドはTextFieldクラス、ボタンはButtonクラスで作成します。ボタンが押された際のアクションはイベント-リスナによって処理します。これもAWT/Swingと同様です。ボタンの場合はクリックされるとActionEventが発生し、それをActionListenerのactionPerformed()メソッドよって受け取ることができます。AWT/Swingと同名のクラス/メソッドですが、これらはnextapp.echo.app.eventパッケージで用意されたEcho用のものなので注意が必要です。
以下に、テキストフィールドとボタンを利用したUIの構成例を示します。イベント処理も含めてAWT/Swingと非常によく似たコードになっていることがわかると思います。
package jp.gihyo.toolbox.echo;
import nextapp.echo.app.*;
import nextapp.echo.app.event.*;
public class TextInput extends ApplicationInstance {
private TextField field = null;
private Label messageLabel = null;
@Override
public Window init() {
Window window = new Window();
window.setTitle("Echo Framworkのサンプル");
// ContentPaneを作成
ContentPane contentPane = new ContentPane();
contentPane.setInsets(new Insets(new Extent(20)));
window.setContent(contentPane);
// Columnレイアウトコンポーネントを作成
Column column = new Column();
contentPane.add(column);
// テキストフィールドを配置
Label fieldLabel = new Label("メッセージを入力してください:");
column.add(fieldLabel);
this.field = new TextField();
this.field.setWidth(new Extent(200));
column.add(this.field);
// ボタンを配置
Button button = new Button("入力");
button.setWidth(new Extent(50));
button.setBorder(new Border(new Extent(2), Color.BLACK, Border.STYLE_DOUBLE));
button.setBackground(Color.LIGHTGRAY);
InputListener buttonListener = new InputListener();
button.addActionListener(buttonListener);
column.add(button);
// フォントを指定してラベルを配置
this.messageLabel = new Label("『』");
Font font = new Font(Font.SANS_SERIF, Font.PLAIN, new Extent(24));
this.messageLabel.setFont(font);
column.add(this.messageLabel);
return window;
}
/* ボタンのクリックイベントを受け取るリスナ */
class InputListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
String message = field.getText();
messageLabel.setText("『" + message + "』");
}
}
}
Columnはコンポーネントを縦に配置するようなコンテナクラスです。Echoには汎用のレイアウトマネージャのような仕組みはなく、代わりにそれぞれのレイアウト用にコンテナクラスが用意されています。
Columnの他にはRowやGridといったコンテナがあります。Buttonにはボーダーや背景色などを指定しています。Echoに用意されたコンポーネントのデフォルトの見た目はあまり洗練されていないため、UIをそれっぽく見せるためにはさまざまなプロパティを自分で調整する必要があります。これはEchoを使う上での少々残念な点です。
TextInputを起動するためのServletクラスは次のようになります。
package jp.gihyo.toolbox.echo;
import javax.servlet.annotation.WebServlet;
import nextapp.echo.app.ApplicationInstance;
import nextapp.echo.webcontainer.WebContainerServlet;
@WebServlet("/textinput")
public class TextInputServlet extends WebContainerServlet {
@Override
public ApplicationInstance newApplicationInstance() {
return new TextInput();
}
}
Webブラウザからアクセスすると、図2のようにテキストフィールドとボタンが表示されるので、メッセージを入力してボタンをクリックすれば、図3のように入力した内容がページに反映されます。
図2 テキストフィールドとボタンを利用したアプリケーションの例
図2 入力した内容がページに反映される
次回は、クライアントサイドのJavaScriptによってアプリケーションを作成する方法を紹介します。