JavaとJavaScriptのデータ型を自動変換するDWRとは
今回のサンプルのプログラム作成ではDWRを使用しています。DWRはAjaxのサーバリモーティングライブラリで、Ajaxクライアント側でのプログラム開発でも有効ですが、むしろサーバ側でのJavaプログラム開発で効果を発揮します。
サーバ側プログラムの構成
DWRを使用した場合のシステム構成が、図10です。
DWRの特徴
DWRの特徴は、次の3つです。
- サーバサイドでは、DWRの専用サーブレットを使用するため、ユーザーはPOJO形式でBeanを記述すればよい
- DWRにはデバッグ機能(DWRデバッグ)があり、この機能でWebブラウザクライアントと接続する前に、サーバ側単独で、Webブラウザから簡単にBeanの動作が確認できる
- Ajax/JavaScriptクライアントからサーバにアクセスする場合は、クラスやメソッドを呼び出すような書式で行える。これは特にJavaプログラマでJavaScriptになじみの少ない人には便利な機能
DWRを使用するための準備
EclipseでDWRを使用するための準備は簡単です。DWRのダウンロードサイトから「dwr.jar」をダウンロードし、図11のように「WEB-INF/lib」フォルダ下に追加すれば、それでOKです。
なお前回もお知らせしましたが、DWRについて詳しく知りたい読者は、下記記事を参照しておいてください。また拙著「Ajaxによる業務アプリケーション開発」(秀和システム)にも、DWRについて詳しく解説されているので、興味のある方は参照してみてください。
コレクションフィールドで、GAEjでもJOIN検索をカバー
ここからは、ようやくサーバ側のプログラムを見ていきます。今回は、JavaBeansでのプログラム記述になります。なおDWRを使用する場合は、サーバ側単独でのデバッグ機能があることから、通常サーバ側からプログラムを作成します。
package jdoajax; import java.io.IOException; import java.util.Date; import java.util.List; import javax.jdo.PersistenceManager; import jdoajax.PMF; import jdoajax.questMsg; public class questBean{ public String addQuest(String q1, List<String> q2, // 【1】 String q3, String comment, String qname, String qmail, String qaddr) { Date date = new Date(); questMsg qmsg = new questMsg(q1,q2,q3,comment,qname,qmail,qaddr,date); // 【2】 PersistenceManager pm = PMF.get().getPersistenceManager(); // 【3】 Transaction tx = pm.currentTransaction(); try { pm.makePersistent(qmsg); // 【4】 } catch(Exception e){ return "NO: 登録不成功 Error = " + e; } finally { pm.close(); // 【5】 } return "OK: 登録成功"; } public String revQuest() { PersistenceManager pm = PMF.get().getPersistenceManager(); // 【6】 String out = ""; String query = "select from jdoajax.questMsg order by date desc range 0,5"; // 【7】 List<questMsg> qMsg = (List<questMsg>)pm.newQuery(query).execute(); // 【8】 if(qMsg.isEmpty()){ out = "NO:msg2 is empty"; }else{ for (questMsg m : qMsg) { String q1_r = m.getQ1(); List<String> q2_l = m.getQ2(); // 【9】 String[] q2_sr = (String[])q2_l.toArray(new String[0]); // 【10】 String q2_r = ""; for(int i=0; i < q2_sr.length;i++){ q2_r += q2_sr[i]+"<c>"; // 【11】 } String q3_r = m.getQ3(); String comment = m.getComment(); String qname_r = m.getQname(); String qmail_r = m.getQmail(); String qaddr_r = m.getQaddr(); Date date_r = m.getDate(); out=out+q1_r+"<i>" +q2_r+"<i>" +q3_r+"<i>" +comment+"<i>" +qname_r+"<i>" +qmail_r+"<i>" +qaddr_r+"<i>" +date_r+"<r>"; } } return out; } }
リスト1は、今回サンプルのJavaBeans(questBean.java)で、アンケート登録用のaddQuestと、アンケート一覧参照で使用されるrevQuestの2種類のメソッドが記述されています。
最初に登録用のaddQuestメソッドを見ていきますが、Bigtableへの永続化手順については、前回見た内容とほぼ同じです。ただし今回は、Bean内の処理で、特にコレクションフィールド、つまりリスト形式データの永続化を行うので、この部分の処理が異なっており、この点に焦点を当てて見ていきます。
コレクションフィールドを持つデータオブジェクトのBigtable登録
図12はアンケート登録用Bigtableのエンティティ構造です。
プロパティQ2の部分がリスト形式になっています。画面からの入力では、Q2項目は最大9個まで選択可能で、選択数に対応してQ2のリスト項目数は変わっていきます。このサンプルでは、Q2だけがリスト形式ですが、Bigtableではキー項目以外の任意のプロパティ項目をリストにでき、リスト項目の数も任意です。
また、今回の例では触れていませんが、エンティティ(≒テーブル)にフィールド(≒テーブル項目)を任意に追加したり、あるいはデータ属性を変えたりすることも可能です。
Bigtableは、このようにエンティティ構造に柔軟性があるため、RDBでの正規化、特に第1正規形でのテーブル分割が必要なくなります。Bigtableには検索時のテーブルJOIN(結合)機能はありませんが、以上のようなBigtableの柔軟な機能を利用することによって、JOIN機能が必要ないエンティティ構造にすることもできるわけです。
次ページでは、引き続きサーバ側の処理について解説し、DWRデバッグでサーバ処理機能を確認する方法を紹介します。
Copyright © ITmedia, Inc. All Rights Reserved.