コントロールのカスタマイズ
前回 に引き続き、「 Play Framework 」( 日本語サイトはこちら )の使い方を解説します。Play Frameworkで作成したアプリケーションはモデル/ビュー/コントロールの各パーツから構成され、それぞれプロジェクトのmodels/views/controllersフォルダ内に格納されています。前回はビューの修正を行ったので、今回はまずコントロールをカスタマイズしてみましょう。
デフォルトのコントロールはcontrollersフォルダにApplication.javaとして作成されています。このindex()メソッドがビューのindex.htmlに関連付けられていることは前回説明しました。index()メソッドでは、次のようにrender()メソッドの呼び出しを行っています。これがPlay Frameworkのテンプレートエンジンを利用してWebページのレンダリングを行う処理です。
public static void index() {
render();
}
render()メソッドにはObject型の引数を渡すことができます。渡した引数は、ビューのテンプレート内で変数として参照することができます。例えば、次のようにrender()にStringの値を渡したとします。
public static void index() {
String message = "ようこそ、Play Frameworkへ!";
render(message);
}
この場合、index.html側ではmessageという変数が利用できるようになり、その値はrender()の呼び出し時に設定されていた「ようこそ、Play Frameworkへ!」という文字列となっています。テンプレート内で、変数の値は「${変数名}」で参照できます。message変数の場合には以下のような具合です。
#{extends 'main.html' /}
#{set title:'Play Frameworkの使用例' /}
<h2>Playで作成したアプリケーションです</h2>
<div>${message}</div>
Webブラウザでページをリロードすると、図1 のようにコントロールから渡されたmessageの値が表示に反映されていることが確認できます。
図1 messageの値が反映されている
なお、render()の引数は可変長なので、同時に複数のオブジェクトを渡すことも可能です。
入力フォームとモデルの利用
続いて、モデルとの連携を行ってみましょう。ここでは、フォームから入力された名前とメールアドレスをデータベースに記録していくというアプリケーションを作ってみます。モデルの定義はJavaクラスで行います。次に示すAddressクラスは、名前とメールアドレスをプロパティに持つモデルを定義した例です。
package models;
import java.util.*;
import javax.persistence.*;
import play.db.jpa.*;
@Entity
public class Address extends Model {
public String name;
public String email;
public Address(String name, String email) {
this.name = name;
this.email = email;
}
}
Play Frameworkでは、モデルの永続化にJPA(Java Persistence API)を利用しています。JPAでは、@Entityアノテーションを使ってデータベースに永続化するエンティティを定義します。Addressクラスが継承しているplay.db.jpa.Modelは、JPAを利用して永続化するクラスの基底クラスになります。作成したAddressクラスはモデルを表すクラスなので、modelsフォルダに配置します。
データベースへの永続化を利用する場合には、confフォルダにある「applocation.conf」ファイルの設定を変更する必要があります。データベースとして付属のH2を利用する場合には、この設定ファイルから「db=mem」と書かれた部分を探して次のようにコメントインしましょう。
# Database configuration
# ~~~~~
# Enable a database engine if needed.
#
# To quickly set up a development database, use either:
# - mem : for a transient in memory database (H2 in memory)
# - fs : for a simple file written database (H2 file stored)
db=mem
#
# To connect to a local MySQL5 database, use:
# db=mysql:user:pwd@database_name
#
# If you need a full JDBC configuration use the following :
# db.url=jdbc:postgresql:database_name
# db.driver=org.postgresql.Driver
# db.user=root
# db.pass=secret
この設定だとH2がインメモリーで実行されます。「 db=fs」とすると、ファイルに記録する形で実行されます。その他、MySQLやPostgreSQLを使う場合には、それぞれデータベースの設定をコメントインして、URLやドライバの設定を行ってください。
さて、フォームからの入力を受け取れるようにビューとコントロールの方も作っていきましょう。まずビューの方は、入力フォームを持ったページのテンプレートを作成する必要があります。以下に例を示します。これを「add.html」として、view/Applicationフォルダに配置しましょう。
#{extends 'main.html' /}
#{set title:'Play Frameworkの使用例' /}
<h1>アドレスの追加</h1>
<form method="post" action="@{Application.add}">
名前: <input type="text" name="name" /><br/>
アドレス: <input type="text" name="email" /><br>
<input type="submit" value="追加" />
</form>
<table border="1">
<tr><th>名前</th><th>アドレス</th></tr>
#{list items:addresses, as:'address'}
<tr><td>${address.name}</td><td>${address.email}</td></tr>
#{/list}
</table>
上のformタグの部分が入力フォームを表示するためのもので、下のtableタブは記録されたアドレスの一覧を表示するためのものです。まずformタグの方から見ていきます。action属性の値には、「 @{クラス名.メソッド名}」というフォーマットで、リクエストを処理するコントロールのメソッドを指定します。この例の場合はApplicationクラスのadd()メソッドということになります。名前とメールアドレスを入力するための入力フィールドには、それぞれname属性の値として"name"、"email"を指定しています。これがコントロール側で値を受け取る際の変数名に対応します。
そのApplicationクラスのadd()メソッドは、次のようなコードになります。
public static void add(String name, String email) {
if ((name!=null && !name.equals("")) ||
(email!=null && !email.equals(""))) {
Address address = new Address(name, email);
address.save();
}
List<Address> addresses = Address.findAll();
render(addresses);
}
フォームから送信された値はメソッドの仮引数として渡されます。この仮引数名が、inputタグのname属性の対応付けられているわけです。この例ではnameとemailの値を使ってAddressオブジェクトを生成するようになっています。そしてAddressのsave()メソッド(play.db.jpa.Modelの親クラスであるplay.db.jpa.GenericModelに用意されたメソッドです)を呼び出すことで、作成したオブジェクトをデータベースに記録しています。
findAll()メソッドは、データベースに記録されたAdressの全エンティティを取得し、Listに格納して返すメソッドです。ここでは取得したListをrender()メソッドに渡してテンプレートで利用できるようにしています。
add.htmlのtableタグの部分に戻りましょう。ここで利用している「#{list ●●●}というのは、Listオブジェクトに対応してfor-each(あるいはJavaの拡張for文)のように使うことができる構文です。上の例ではrender()メソッドにadressesという変数名でListオブジェクトが渡されています。この要素それぞれが順番にaddress変数に格納されて処理されるということです。つまり、データベースに記録されている全Addressオブジェクトの名前とメールアドレスを、trタグで順番に出力するということになります。
最後に、add.htmlとApplication.add()メソッドとの関連付けの設定を、confフォルダのroutesファイルに追加します。今回はPOSTメソッドでリクエストを処理しているので、次のようにPOSTの設定を追加する必要があります。
POST /add Application.add
以上で完成です。Webブラウザで「http://localhost:9000/add」にアクセスすると、最初はデータが登録されていないので図2 のように表示されます。フォームから名前とアドレスを追加していくと、図3 のようにテーブルに一覧が表示されるようになります。
図2 入力フォームが表示される
図3 追加されたアドレスはテーブルに一覧表示される
NerBeans/Eclipseでの利用方法
最後に、Play Frameworkで作成したプロジェクトをNetBeansで編集する方法を紹介します。コマンドプロンプトから次のコマンドを実行してください。
> play netbeansify myapp
コマンドが成功すると、myapp/nbprojectフォルダにNetBeans用の設定ファイルが生成されます。これで、myappプロジェクトがNetBeansで開けるようになります。同様に次のコマンドでEclipse用の設定ファイルを作ることもできます。
> play eclipsify myapp
Play Frameworkは、Webアプリケーションを実に軽快に開発できるようにしてくれるフレームワークです。モデル/ビュー/コントロールの分離が明解であることや、それぞれの関連付けがほぼ自動で行われること、プログラム修正後の再配備が不要なこと、オブジェクトの永続化が容易なことなど、多くのメリットがあります。ストレスフリーな開発のために一度試してみる価値のあるツールと言えるでしょう。