今回は、JSF(JavaServer Faces)コンポーネント・スイートの「PrimeFaces」を用いて、UIコンポーネントとサーバ側のManagedBeanオブジェクトを連携させる例を紹介する。具体的には、フォームから入力されたメッセージをサーバ側のオブジェクトに記録し、その内容をテーブルでページに表示するというアプリケーションを作ってみる。
ManagedBeanの作成
まず、送られたメッセージを保持するためのクラスをMessageクラスとして、次のように定義する。このクラスはプロパティとしてString型の"name"と"value"を持つ。
package jp.co.mycom.toolde.primefaces;
import java.io.Serializable;
public class Message implements Serializable {
private String name = null;
private String value = null;
public String getName() {
return name;
}
public String getValue() {
return value;
}
public void setName(String name) {
this.name = name;
}
public void setValue(String value) {
this.value = value;
}
}
ManagedBeanは、フォームから入力されたメッセージを受け取って記憶し、その一覧をテーブルに反映させるというものである。今回はAddMessageBeanクラスとして、次のように実装した。
package jp.co.mycom.toolde.primefaces;
import java.util.List;
import java.util.ArrayList;
public class AddMessageBean {
private Message message = new Message();
private List<Message> messages = new ArrayList<Message>();
public void addMessage() {
this.messages.add(this.message);
this.message = new Message(); // フォームのリセット
}
public Message getMessage() {
return this.message;
}
public void setMessage(Message message) {
this.message = message;
}
public List<Message> getMessages() {
return this.messages;
}
}
AddMessageBeanクラスは"message"と"messages"という2つのプロパティを持つ。messageは単体のMessageオブジェクトであり、フォームから入力された最新のメッセージと名前を保持する。一方でmessagesはMessageを格納するListオブジェクトであり、それまでに入力されたメッセージ/名前を記憶するためのものである。
このクラスにはもうひとつ、addMessage()メソッドが定義してある。これはユーザがメッセージの送信ボタンを押したときに呼び出され、そのときにmessageプロパティが保持しているMessageオブジェクトをmessagesに追加するという役割のメソッドである。追加後は、フォームの中身を空にするために、messageプロパティに新しいMessageオブジェクトを格納する。
このAddMessageBeanクラスをManagedBeanとして利用可能にするために、faces-config.xmlには次のような設定を追加する。
<managed-bean>
<managed-bean-name>addMessageBean</managed-bean-name>
<managed-bean-class>jp.co.mycom.toolde.primefaces.AddMessageBean</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
この設定により、HTML側では"addMessageBean"という名称でサーバ側のAddMessageBeanオブジェクトにアクセスできる。スコープは"session"にしたので、Webブラウザとアプリケーションの間にセッションが確立している間は記憶されたデータが有効になる。もしもっと長期間データを保持しておきたい場合には、addMessage()の部分にMessageオブジェクトの永続化の機構を組み込めばいいということになる。
PrimeFacesのコンポーネントとの連携
続いてWebブラウザに表示するUIを作成する。必要なコンポーネントはメッセージと名前を入力するテキストフィールドと、送信用のボタン、そして登録されたメッセージを一覧表示するテーブルである。テキストフィールドは、PrimeFacesでは
<p:inputText id="name" value="#{addMessageBean.message.value}" required="true" label="Name"/>
この例の場合、value属性の値(すなわち入力されたテキスト)を、サーバ側のAddMessageBeanオブジェクトのmessageプロパティのvalueの値に関連付けている。
ボタンは
<p:commandButton value="送信" action="#{addMessageBean.addMessage}" update="@form"/>
テーブルは
<p:dataTable value="#{addMessageBean.messages}" var="message">
<p:column>
<f:facet name="header">
<h:outputText value="名前" />
</f:facet>
<h:outputText value="#{message.name}" />
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="メッセージ" />
</f:facet>
<h:outputText value="#{message.value}" />
</p:column>
</p:dataTable>
以上をまとめると、XHTMLによるページは次のように記述できる。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.prime.com.tr/ui">
<h:head>
<title>PrimeFacesのサンプル</title>
</h:head>
<h:body>
<h1>メッセージボード</h1>
<h:form>
<h:panelGrid columns="2">
<h:outputLabel value="名前 :" for="name" />
<p:inputText id="name" value="#{addMessageBean.message.name}" required="true" label="Name"/>
<h:outputLabel value="メッセージ :" for="message" />
<p:inputText id="message" value="#{addMessageBean.message.value}" required="true" label="Message"/>
</h:panelGrid>
<p:commandButton value="送信" action="#{addMessageBean.addMessage}" update="@form"/>
<p:dataTable value="#{addMessageBean.messages}" var="message">
<p:column>
<f:facet name="header">
<h:outputText value="名前" />
</f:facet>
<h:outputText value="#{message.name}" />
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="メッセージ" />
</f:facet>
<h:outputText value="#{message.value}" />
</p:column>
</p:dataTable>
</h:form>
</h:body>
</html>
完成したら、アプリケーションサーバに配備してWebブラウザからアクセスしてみよう。最初はのように表示され、名前とメッセージを入力していくとのようにテーブルに入力した名前/メッセージが反映されていく。
テーブルをソート可能にする
テーブルのデータをカラムごとにソートできるようにするには、対象とするカラムの Webブラウザからアクセスすると、のようにカラム名の部分をクリックすると昇順/降順にソートされるようになっていることが確認できる。 テーブルに対してフィルタの機能を付け加えることも簡単にできる。ソートの場合と同様に、 Webページ上の表示では、のようにカラム名にフィルタリングのための入力フィールドが表示される。ここに文字列を入力すると、のように条件にマッチした行だけが表示されるようになる。 今回は一部のコンポーネントの使い方と、ManagedBeanとの連携のさせ方を紹介したが、PrimeFacesの最大の強みはそのコンポーネントの数である。どのようなコンポーネントが用意されているかは、公式サイトのショーケースにまとめられている。<p:dataTable value="#{addMessageBean.messages}" var="message">
<p:column sortBy="#{message.name}">
<f:facet name="header">
<h:outputText value="名前" />
</f:facet>
<h:outputText value="#{message.name}" />
</p:column>
<p:column sortBy="#{message.value}">
<f:facet name="header">
<h:outputText value="メッセージ" />
</f:facet>
<h:outputText value="#{message.value}" />
</p:column>
</p:dataTable>
テーブルにフィルタ機能を付ける
<p:dataTable value="#{addMessageBean.messages}" var="message">
<p:column sortBy="#{message.name}" filterBy="#{message.name}">
<f:facet name="header">
<h:outputText value="名前" />
</f:facet>
<h:outputText value="#{message.name}" />
</p:column>
<p:column sortBy="#{message.value}" filterBy="#{message.value}" filterMatchMode="startsWith">
<f:facet name="header">
<h:outputText value="メッセージ" />
</f:facet>
<h:outputText value="#{message.value}" />
</p:column>
</p:dataTable>