連載
» 2007年04月10日 00時00分 公開

O/Rマッピングで郵便番号検索Ajaxアプリ作成!MyEclipseでAjax+Javaをやさしく開発(3)(3/4 ページ)

[水島和憲,エクリプス]

DWRを利用した郵便番号検索

 今回の解説のポイントは、JavaScriptとJava間でのデータ変換と、DWRが提供するユーティリティ機能についてです。なお、あらかじめweb.xmlの設定は前回と同じ設定をしておいてください。

DWRでのJavaScriptとJava間のデータ変換はやさしい

 前回の連載で強調したDWRの特徴は、JavaScriptからあたかもJavaオブジェクトのメソッドを呼び出すかのようにサーバ側のJavaオブジェクトを呼び出せることでした。JavaScriptに不慣れなJava開発者であっても、面倒な非同期通信を気にする必要がありませんでした。

 DWRのもう1つの大きな特徴は、JavaScriptとJavaの間で相互にデータを送受信するときに変換方式を特別気にする必要がないことです。intlongStringなどのJavaの基本的な型であれば、何も設定しなくても、デフォルトで自動的に相互変換してくれます。また、配列java.util.Collectionjava.util.Mapもデフォルトで変換されます。Collection型の要素がCollection型であっても、再帰的に変換されます。

 ただし、BeanObjectについては、デフォルトで自動的には変換されません。なぜでしょうか。理由はセキュリティです。JavaScriptから勝手にサーバ側のコードに触れるのは問題が多いため、明示的に指定されたBeanだけが変換されます。さらに、アクセスできるBeanのプロパティも制限できます。

「convert」タグでDWRに変換の通知

 変換することを明示的にDWRに通知するのが、dwr.xmlの「convert」タグです。次のように記述します。

<convert convetter="bean" match="your.package.Klazz"/>

 これは、your.package.Klazzという1つのBeanだけが変換可能になります。次のように、アスタリスクを使って記述すると、パッケージyour.package配下のクラスおよびサブパッケージのクラスすべてが有効になります。

<convert convetter="bean" match="your.package.*"/>

「param」タグで公開するプロパティを制限

 公開するプロパティを制限するには、「convert」タグの要素として次のように、「param」タグを指定します。公開しないプロパティを指定し、それ以外のプロパティは公開する方法(exclude)と、公開するプロパティを指定し、それ以外のプロパティは公開しない方法(include)があります。

<convert convetter="bean" match="your.package.Klazz">
    <param name="exclude" value="prop1, prop2"/>
</convet>

 上記の例では、クラスKlazzのprop1とprop2のプロパティにはアクセスできませんが、そのほかのプロパティにはアクセスできます。

<convert convetter="bean" match="your.package.Klazz">
    <param name="include" value="prop1, prop2"/>
</convet>

 この例の場合、JavaScriptからprop1とprop2にはアクセスできますが、それ以外のプロパティにはアクセスできません。

dwr.xmlを設定

 今回のサンプルアプリケーションでは、PostaldataDAOのfindメソッドだけを呼び出します。このメソッドの引数は、すべてStringです。従って、引数についてConverterを指定する必要はありません。

 一方、メソッドが返す値はPostaldataのListになります。Listはデフォルトで変換されますが、Postaldataは自動的に変換されないので、「convert」タグで明示的に指定する必要があります。Postaldataの全プロパティにアクセスするため、プロパティへの制限は課しません。呼び出すオブジェクトのCreatorと併せて、dwr.xmlは次のようになります。

dwr.xml
<dwr>
    <allow>
        <create javascript="post" creator="new">
           <param name="class" value="com.hoge.orm.PostaldataDAO" />
        </create>
        <convert converter="bean" match="com.hoge.orm.Postaldata" />
    </allow>
</dwr>

3つのJavaScriptファイル

 前回の復習になりますが、DWRを使用する場合はHTMLのmetaタグに次のおまじないが必要です。

<script type="text/javascript" src="dwr/interface/post.js"></script>
<script type="text/javascript" src="dwr/engine.js"></script>
<script type="text/javascript" src="dwr/util.js"></script>

 最初の行は、dwr.xmlの「create」タグのjavascript属性で指定した名前に「.js」拡張子を付けます。このJavaScriptファイルは、サーバ側のJavaオブジェクトにアクセスするためのプロキシーであり、DWRによって自動的に生成されます。

 2行目のengine.jsはDWRのコアとなるJavaScriptであり、DWRを使用するときには必ず読み込まなければなりません。

 3行目のutil.jsは、DWRのユーティリティであり、便利な機能がいろいろと用意されています。後ほど、その一部を紹介します。

JavaScriptから呼び出すには?

 郵便番号検索のページは、図1のように単純な表形式になっています。郵便番号、都道府県名、市町村名、地域名のいずれかに文字を入力すると、それぞれの値をアンド条件として検索します。

図1 DWRの概要 図1 郵便番号検索(「富士見」と名の付く東京都の郵便番号を検索した例)(クリックすると、画面が拡大します)

 上記、図1のHTMLは次のようになります。テーブルのヘッダ部分には郵便番号、都道府県名、市町村名、地域名それぞれに入力ボックスがあり、何らかの文字が入力されると、「psearch()」というJavaScriptの関数が呼び出されます。テーブルのボディ部分()は、resultsというidを持っています(A)。最初は空ですが、検索が実行されると、ここに結果が挿入されます。

<table border="1">
  <thead>
    <tr>
      <th>#</th>
      <th>
        郵便番号<br />
        <input type="text" id="zip" onkeyup="psearch();" />
      </th>
      <th>
        都道府県名<br />
        <input type="text" id="pref" onkeyup="psearch();" />
      </th>
      <th>
        市町村名<br />
        <input type="text" id="city" onkeyup="psearch();" />
      </th>
      <th>
        地域名<br />
        <input type="text" id="town" onkeyup="psearch();" />
      </th>
    </tr>
  </thead>
  <tbody id="results"></tbody>       ← (A)
</table>

 検索するJavaScriptのコードは次のようになります。前回も説明したDWRUtil.getValue()は引数で指定したIDの要素の値を取り出します。post.find()でサーバのオブジェクトが呼び出されます。サーバ側のメソッドと同じ順序でパラメータを指定し、最後にコールバック関数を指定します。サーバ側のメソッド呼び出しは、Ajaxの非同期通信によって呼び出されます。コールバック関数は、非同期に呼び出されたメソッドが終了したときに、呼ばれます。メソッドの復帰値はコールバック関数の引数で受け取れます。

    function psearch() {
        var _zip = DWRUtil.getValue( "zip" ) + "%";
        var _pref = DWRUtil.getValue( "pref" ) + "%";
        var _city = DWRUtil.getValue( "city" ) + "%";
        var _town = DWRUtil.getValue( "town" ) + "%";
        post.find( _zip, _pref, _city, _town,updateTab );
    }

 コールバック関数updateTabの内容を順に説明します。この関数の中でDWRのユーティリティを利用しています。

 事前に検索した結果が表示されている場合、まずそれをクリアする必要があります。その処理を行うのが、DWRUtil.removeAllRows( "results" );です。DWRUtil.removeAllRows()を呼び出すと、引数に指定されたIDの要素が削除されます。今回の場合、検索結果が表示されるテーブルのボディ部分(results)が削除されます。

 次に、検索結果をテーブルに追記します。その処理が DWRUtil.addRows( "results", lst , cellFuncs);です。DWRUtil.addRows(id, lst, cellFuncs)はidで指定されたテーブルにlstの値を行に加工して追加します。cellFuncsは関数のリストです。lstの各要素はcellFuncs中の各関数に引数として渡され、加工できます。

    function updateTab( lst ) {
        count = 1;
        DWRUtil.removeAllRows( "results" );
        DWRUtil.addRows( "results", lst , cellFuncs);
    }

    var count = 1;
    var cellFuncs = [
        function(data) { return count++; },
        function(data) { return data.zipcode; },
        function(data) { return data.pref; },
        function(data) { return data.city; },
        function(data) { return data.town; }
    ];

 以上で、郵便番号検索の基本的な動作部分が完了しました。

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。