最初に図4のアンケート画面上のQ2のチェックボックス選択項目が、リスト1では【1】のように文字列のリストとして受け取られています。
この部分で早速DWRの機能が発揮されています。DWRでは、JavaScriptで記述されたクライアントと、Javaで記述されたサーバ間でのデータ型の変換を自動的に行ってくれます。
例えば、このサンプルの場合、Webブラウザ側からはJavaScriptの配列としてサーバ側に送信し、これをJavaでは文字列リスト形式で受け取っていますが、この2つの言語間のデータ型変換はDWRが自動的に行ってくれるのです。
リスト1の【2】では、永続化対象エンティティ(≒レコード)と処理定義のクラス(下記リスト2のquesMsg.java)のインスタンスを生成しています。コンストラクタ引数に、クライアントから送信されたパラメータをすべて指定しており、これまでも見てきたように、quesMsg.java(リスト2)のコンストラクタ内で永続化対象データの値が設定されます。
この処理でリスト形式データのq2に関係する部分はリスト2の【1】〜【4】になっています。
package jdoajax;
import java.util.Date;
import java.util.List;
import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.IdentityType;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;
@PersistenceCapable(identityType = IdentityType.APPLICATION)
public class questMsg {
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
private Long id;
@Persistent
private String q1;
@Persistent // 【1】
private List<String> q2; // 【1】
@Persistent
private String q3;
@Persistent
private String comment;
@Persistent
private String qname;
@Persistent
private String qmail;
@Persistent
private String qaddr;
@Persistent
private Date date;
public questMsg(String q1,
List<String> q2, // 【2】
String q3,
String comment,
String qname,
String qmail,
String qaddr,
Date date) {
this.q1 = q1;
this.q2 = q2; // 【3】
this.q3 = q3;
this.comment = comment;
this.qname = qname;
this.qmail = qmail;
this.qaddr = qaddr;
this.date = date;
}
public Long getId() { return id; }
public String getQ1() { return q1; }
public List<String> getQ2() { return q2; }
public String getQ3() { return q3; }
public String getComment() { return comment; }
public String getQname() { return qname; }
public String getQmail() { return qmail; }
public String getQaddr() { return qaddr; }
public Date getDate() { return date; }
public void setQ1(String q1) { this.q1 = q1; }
public void setQ2(List<String> q2) { this.q2 = q2; } // 【4】
public void setQ3(String q3) { this.q3 = q3; }
public void setComment(String comment) { this.comment = comment; }
public void setQname(String qname) { this.qname = qname; }
public void setQmail(String qmail) { this.qmail = qmail; }
public void setQaddr(String qaddr) { this.qaddr = qaddr; }
public void setDate(Date date) { this.date = date; }
}
リスト1では、【2】での処理の後、【3】でPersistenceManageactoryのインスタンスを生成して【4】で永続化処理を行い、【5】でクローズしています。pmインスタンスの生成・処理では、リスト3のPMF.javaを使用しますが、これは前回までと同じです。
package jdoajax;
import javax.jdo.JDOHelper;
import javax.jdo.PersistenceManagerFactory;
public final class PMF {
private static final PersistenceManagerFactory pmfInstance =
JDOHelper.getPersistenceManagerFactory("transactions-optional");
private PMF() {}
public static PersistenceManagerFactory get() {
return pmfInstance;
}
}
参照処理は、revQuestメソッドでJDOQLを使用して行われます。【6】でpmインスタンスを生成した後、【7】でSQLに類似した検索文を定義しています。検索パラメータでは「order by date desc」で日付降順でのソート、「range 0,5」でソート並び先頭から5つのデータを検索することを指定しています。
【8】では、クエリインスタンスの生成とクエリ実行を1行で行っていますが、分解すると、以下のような手順になります。
1.クエリ文字列生成
String ql = "select from jdoajax.questMsg order by date desc range 0,5";
2.クエリインスタンスの生成
Query query = pm.newQuery(ql);
3.クエリ実行
List<questMsg> qMsg = (List<questMsg>) query.execute();
リスト形式で格納されているQ2データは【9】の「m.getQ2();」で取得され、q2_lにリストデータとして格納されます。ここでは、JavaScriptクライアントにこのデータを文字列並びとして返しており、そのための変換処理が【10】で行われています。
String[] q2_sr = (String[])q2_l.toArray(new String[0]); // 【10】
リスト変数q2_lにtoArrayメソッドを適用すると、リストデータ(コレクション)が配列に変換されます。この例でのtoArrayメソッドでは引数に「new String[0]」を指定しています。ここで、「toArray(Object[])」メソッドの引数に要素が0個の配列をセットすると、引数にセットされた配列と同じ型で、当該Collectionの全要素がセットされた新規配列が返されます。
最後に【11】では、文字列配列を
DWRを使用した開発ではサーバ側のプログラム作成を最初に行い、クライアントとの接続の前に「DWRデバッグ」機能でサーバ側ファンクションの動作を確認します。図13はDWRデバッグ画面で、revQuestメソッドの全件参照機能を確認しています。
DWRを使用する場合は、web.xmlの記述をリスト4のように変更します。web.xmlの内容は定型的な内容で、DWRのダウンロードサイトでダウンロードできるDWRのソースコードに付属するweb.xmlをそのまま使用できます。
<?xml version="1.0" encoding="utf-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4">
<servlet>
<servlet-name>dwr-invoker</servlet-name>
<servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>
<--【1】始まり-->
<init-param>
<param-name>debug</param-name>
<param-value>true</param-value>
</init-param>
<--【1】終わり-->
<init-param>
<param-name>pollAndCometEnabled</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>activeReverseAjaxEnabled</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>maxWaitAfterWrite</param-name>
<param-value>500</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dwr-invoker</servlet-name>
<url-pattern>/dwr/*</url-pattern>
</servlet-mapping>
<--【2】始まり-->
<welcome-file-list>
<welcome-file>dwrMenu.htm</welcome-file>
</welcome-file-list>
<--【2】終わり-->
</web-app>
DWRでは、用意された専用のサーブレット(dwr-invoker)を使用するため、ユーザーサーブレットの記述は必要ありません。ただし、このサンプルでは、初期表示のメニュー画面を【2】で追加しています。また【1】は、DWRデバッグ機能を有効にするための指定で、DWRのサンプルに標準で記述されています。
次に、DWRでクライアントからリクエストする場合に、DWRサーブレットが「どのJavaBeansを呼び出せばよいか」を指定するためのdwr.xmlを定義します。
なお、dwr.xmlの定義に変えてアノテーションで指定する方法もあります。リスト5では2種類のBeanファイルが定義されていますが、赤字の部分がサンプル用の記述です。
<!DOCTYPE dwr PUBLIC
"-//GetAhead Limited//DTD Direct Web Remoting 1.0//EN"
"http://www.getahead.ltd.uk/dwr/dwr10.dtd">
<dwr>
<allow>
<create creator="new" class="jdoajax.commentBean" javascript="commentBean"/>
<create creator="new" class="jdoajax.questBean" javascript="questBean"/>
</allow>
</dwr>
次ページでは、最後にクライアント側の処理を見ていきます。
Copyright © ITmedia, Inc. All Rights Reserved.