Google App Engineで手軽に試すJavaクラウド
連載インデックスへ
Google App Engineで手軽に試すJavaクラウド(終)

コレクションフィールドとDWRで、GAEjを業務用に進化


有限会社サイバースペース
清野克行
2009/7/17


リスト形式データ永続化のプログラム処理

 最初に図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】になっています。

  リスト2 questMsg.java
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を使用しますが、これは前回までと同じです。

  リスト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】で行われています。

  リスト1から抜粋
String[] q2_sr = (String[])q2_l.toArray(new String[0]);   // 【10】

 リスト変数q2_lにtoArrayメソッドを適用すると、リストデータ(コレクション)が配列に変換されます。この例でのtoArrayメソッドでは引数に「new String[0]」を指定しています。ここで、「toArray(Object[])」メソッドの引数に要素が0個の配列をセットすると、引数にセットされた配列と同じ型で、当該Collectionの全要素がセットされた新規配列が返されます。

 最後に【11】では、文字列配列を<c>区切りの文字列並びに変換し、この形でJavaScriptクライアントに送信されます。

DWRデバッグでサーバ処理を確認するには?

 DWRを使用した開発ではサーバ側のプログラム作成を最初に行い、クライアントとの接続の前に「DWRデバッグ」機能でサーバ側ファンクションの動作を確認します。図13はDWRデバッグ画面で、revQuestメソッドの全件参照機能を確認しています。

図13 DWRデバッグ画面
図13 DWRデバッグ画面

web.xmlの記述

 DWRを使用する場合は、web.xmlの記述をリスト4のように変更します。web.xmlの内容は定型的な内容で、DWRのダウンロードサイトでダウンロードできるDWRのソースコードに付属するweb.xmlをそのまま使用できます。

  リスト4 ディプロイメントディスクリプタ(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.xmlの記述

 次に、DWRでクライアントからリクエストする場合に、DWRサーブレットが「どのJavaBeansを呼び出せばよいか」を指定するためのdwr.xmlを定義します。

 なお、dwr.xmlの定義に変えてアノテーションで指定する方法もあります。リスト5では2種類のBeanファイルが定義されていますが、赤字の部分がサンプル用の記述です。

  リスト5 dwr.xml
<!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>

 次ページでは、最後にクライアント側の処理を見ていきます。

1-2-3-4

 Index
最終回 コレクションフィールドとDWRで、GAEjを業務用に進化
  Page1
DWRのサーバリモーティングも使って開発効率化
Yahoo! UI Libraryを使ったアンケートのGAEjサンプル
コラム 「GAEでプログラム数の制限を解除するには」
  Page2
JavaとJavaScriptのデータ型を自動変換するDWRとは
コレクションフィールドで、GAEjでもJOIN検索をカバー
Page3
DWRデバッグでサーバ処理を確認するには?
  Page4
JavaScript側で、どのようにJavaメソッドを呼び出すのか
クラウドは、これからが興味深い




Java Solution全記事一覧



TechTargetジャパン

Java Solution フォーラム 新着記事

@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

RSSフィード

キャリアアップ

- PR -
@IT Sepcial

イベントカレンダー

PickUpイベント

- PR -
もっと見る
- PR -

お勧め求人情報

ホワイトペーパーTechTargetジャパン

@IT Sepcial
ソリューションFLASH