最後に、Ajax/JavaScriptクライアントのコードを概要レベルで見ていきます。今回のクライアントコードはXHTMLのタグ記述とJavaScript記述がファイル単位で分かれています。
登録処理画面では、リスト6とリスト7のdwrAddQuest.htmとdwrAddQuest.jsの組み合わせで、一覧参照画面では、リスト8とリスト9のdwrRevQuest.htmと dwrRevQuest.jsの組み合わせで使用されます。
このほかにも今回はjQueryやYUIなどのライブラリも使用しているため外部JavaScriptファイルの数が増え、「jslib」フォルダの内容は図14のようになっています。
jQueryについては前回見ているので省略し、今回はDWRでのサーバアクセスを中心に見ていきます。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja"> <head> <title>questionarie2</title> <link type="text/css" rel="stylesheet" href="/csslib/style.css" /> <--【1】始まり--> <script type="text/javascript" src="/dwr/interface/questBean.js"></script> <script type="text/javascript" src="/dwr/engine.js"></script> <script type="text/javascript" src="/dwr/util.js"></script> <--【1】終わり--> <script type="text/javascript" src="/jslib/jquery-1.3.2.min.js"></script> <script type="text/javascript" src="/jslib/yahoo-dom-event.js?_yuiversion=2.5.0"></script> <script type="text/javascript" src="/jslib/animation.js?_yuiversion=2.5.0"></script> <script type="text/javascript" src="/jslib/dwrAddQuest.js"></script> <--【2】--> </head> <body> <nobr id="demo"><img src="/imglib/app.png" width="140" height="105"/></nobr> <nobr><img src="/imglib/pic0.png" width="140" height="105"/></nobr> <nobr><img src="/imglib/pic1.png" width="140" height="105"/></nobr> <nobr><img src="/imglib/pic2.png" width="140" height="105"/></nobr> <br/><br/> <table> <tr align="center"><td class="t3" width="380">** Google App Engine アンケート **</td> <td id="status" width="180" style="background-color:#ffddaa"></td> <td> <a href="dwrMenu.htm">メイン画面へ戻る</a></td> </tr> </table><br/> Q1.Google App Engineをどのくらい利用しますか。<br> <div style="margin-left:20px"> <table border="0"> <tr> <td id="q1"> <input type="radio" name="q1" id="q1_1" value="ほぼ毎日">ほぼ毎日 <input type="radio" name="q1" id="q1_2" value="週1回以上">週1回以上 <input type="radio" name="q1" id="q1_3" value="月1回以上">月1回以上 <input type="radio" name="q1" id="q1_4" value="数回利用したことがある">数回利用したことがある <input type="radio" name="q1" id="q1_5" value="今回が初めて">今回が初めて </td> </tr> </table> </div><br/> Q2.Google App Engineをどこで知りましたか(複数選択可)。<br> <div style="margin-left:20px"> <table id="q2" border="0" width="600"> <tr> <td><input type="checkbox" name="q2" id="q2_1" value="検索エンジンで(国内サイト)">検索エンジンで(国内サイト)</td> <td><input type="checkbox" name="q2" id="q2_2" value="検索エンジンで(海外サイト)">検索エンジンで(海外サイト)</td> <td><input type="checkbox" name="q2" id="q2_3" value="Web記事で">Web記事で</td> </tr> <tr> <td><input type="checkbox" name="q2" id="q2_4" value="雑誌・新聞などで">雑誌・新聞などで</td> <td><input type="checkbox" name="q2" id="q2_5" value="書籍からの情報">書籍からの情報</td> <td><input type="checkbox" name="q2" id="q2_6" value="人に聞いて">人に聞いて</td> </tr> <tr> <td><input type="checkbox" name="q2" id="q2_7" value="展示会・学会などの展示で">展示会・学会などの展示で</td> <td><input type="checkbox" name="q2" id="q2_8" value="ポスター・パンフレットで">ポスター・パンフレットで</td> <td><input type="checkbox" name="q2" id="q2_9" value="そのほか">そのほか</td> </tr> </table> </div><br/> Q3.サイトの画面表示は分かりやすいですか。<br/><br/> <div style="margin-left:20px"> <select id="q3"> <option value="q3_0" id="q3_0"><=======選択=======></option> <option value="q3_1" id="q3_1">非常に分かりやすい</option> <option value="q3_2" id="q3_2">特に不自由は感じない</option> <option value="q3_3" id="q3_3">やや分かりにくい</option> <option value="q3_4" id="q3_4">非常に分かりにくい</option> </select> </div><br/> そのほか、コメントをお書きください:<br/> <textarea id="comment" id="q4" rows="4" cols="75"></textarea><br/><br/> <hr> <nobr>お名前: <input type="text" id="qname" size="15" maxlength="45"/> E-Mail: <input type="text" id="qmail" size="30" maxlength="90"/> <input type="button" id="add" value="書き込み"/> </nobr></br> <div>住所: <input type="text" id="qaddr" size="80" maxlength="320"/></div> </body> </html>
リスト6は登録用のXHTMLファイルです。今回は外部JavaScriptファイルの指定が増えていますが、【1】の部分がDWR用になっており3個のJavaScriptファイルが指定されています。
最初の指定では、「/dwr/interface」後の指定が呼び出されるBeanごとに違ってきますが、dwr.xml(リスト5)のJavaScriptパラメータで指定された名前を記述するようになっています。次のengine.jsはDWRでのサーバ通信に必須で、最後のutil.jsはユーティリティで必須ではありませんが通常engine、utilの2つとも指定します。
また、【2】は分離したリスト7のJavaScriptファイル指定になっています。
//<![CDATA[ var q1 ="NA"; var q2cum = new Array(); var q2 = new Array(); var q3 ="NA"; var query = {}; $(function(){ attributes = { points: {to: [596, 17], control: [[300, 100], [800, 800]]} }; anim = new YAHOO.util.Motion('demo', attributes); var timerid = setInterval("animation()", 2000); $("#q1").click(function(e){ q1 = e.target.id; }); $("#q2").click(function(e){ q2cum.push(e.target.id); }); $("#q3").change(function(e){ q3 = $("#q3").val(); }); $("#add").click(addqs); }); function animation(){ attributes = { points: {to: [596, 17], control: [[300, 100], [800, 800]]} }; anim = new YAHOO.util.Motion('demo', attributes); anim.animate(); clearInterval(timerid); } function addqs(){ for(var i = 0; i < q2cum.length; i++){ if(document.getElementById(q2cum[i]).checked == true){ q2.push(q2cum[i]); } } var comment = $("#comment").val(); var qname = $("#qname").val(); var qmail = $("#qmail").val(); var qaddr = $("#qaddr").val(); questBean.addQuest(q1, q2, q3, comment, qname, qmail, qaddr, function(resp){ $("#status").text(resp); }); } //]]>
リスト7で、赤字の部分がDWRを使用した場合のサーバ呼び出しです。DWRではJavaに類似した書式でサーバ呼び出しを行うようになっており、questBeanは呼び出されるサーバ側のクラスファイル名で、addQuestは、その中のメソッド名です。q1からqaddrまではサーバに送信されるパラメータ指定ですがこの中でq2は配列データです。
このように、サーバへは配列データをリクエスト送信することも可能です。前に見たように、この配列データはサーバ側で文字列のリストとして受け取られることになります。
最後の匿名関数は、サーバからのレスポンス受信時に自動的に起動され、引数respに渡されるレスポンスデータを使用してステータスを表示しています。
最後に、リスト8・9の一覧参照の場合も基本的な処理方式はほとんど同じです。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja"> <head> <title>アンケートデータ参照</title> <link type="text/css" rel="stylesheet" href="/csslib/style.css" /> <script type="text/javascript" src="/dwr/interface/questBean.js"></script> <script type="text/javascript" src="/dwr/engine.js"></script> <script type="text/javascript" src="/dwr/util.js"></script> <script type="text/javascript" src="/jslib/jquery-1.3.2.min.js"></script> <script type="text/javascript" src="/jslib/dwrRevQuest.js"></script> </head> <body> <h2>アンケート参照</h2> <input type="button" id="rev" value=" 参照 "/> <a href="dwrMenu.htm">メイン画面へ戻る</a> <p id="show"></p> </body> </html>
//<![CDATA[ q1text = new Array(); q1text["q1_1"] = "ほぼ毎日"; q1text["q1_2"] = "週1回以上"; q1text["q1_3"] = "月1回以上"; q1text["q1_4"] = "数回利用したことがある"; q1text["q1_5"] = "今回が初めて"; q2text = new Array(); q2text["q2_1"] = "検索エンジンで(国内サイト)"; q2text["q2_2"] = "検索エンジンで(海外サイト)"; q2text["q2_3"] = "Web記事で"; q2text["q2_4"] = "雑誌・新聞等で"; q2text["q2_5"] = "書籍からの情報"; q2text["q2_6"] = "人に聞いて"; q2text["q2_7"] = "展示会・学会等の展示で"; q2text["q2_8"] = "ポスター・パンフレットで"; q2text["q2_9"] = "そのほか"; q3text = new Array(); q3text["q3_0"] = "選択なし"; q3text["q3_1"] = "非常に分かりやすい"; q3text["q3_2"] = "特に不自由は感じない"; q3text["q3_3"] = "やや分かりにくい"; q3text["q3_4"] = "非常に分かりにくい"; $(function(){ $("#rev").click(function(){ questBean.revQuest(showResp); });}); function showResp(resp){ var tag = ""; var recs = resp.split("<r>"); for (var i = 0; i < recs.length - 1; i++) { var rec = recs[i].split("<i>"); var q2items = rec[1].split("<c>"); var q2list = ""; for (var j=0; j < q2items.length -1; j++){ q2list += q2text[q2items[j]]+" "; } tag += "<hr color='#0000cd'/><div>Q1: " + q1text[rec[0]] + "</div>" + "<div>Q2: " + q2list + "</div>" + "<div>Q3: " + q3text[rec[2]] + "</div>" + "<div>コメント: " + rec[3] + "</div>" + "<div>名前: " + rec[4] + " E-mail: "+rec[5] + "</div>" + "<div>住所: " + rec[6] + "</div>" + "<div>登録日: " + rec[7] + "</div><br/>"; } $("#show").html(tag); } //]]>
赤字の部分がDWRでのサーバリクエスト送信処理です。これは、ID値「rev」の参照ボタンクリックで起動されます。ただし、このプログラムではサーバからのレスポンス受信処理をrevQuestの引数に指定した関数showRespで行っています。
以上、今回で本連載は終了です。本連載では、主にBigtableに焦点を当ててGAEjを見てきましたが、Bigtableの技術的な面白さはここで取り上げてきた内容以外にもまだまだたくさんありますので、以下の連載を参照してください。
ところで、クラウドの対抗勢力と思われていたマイクロソフトもクラウドに参入しており、米マイクロソフトCEOのスティーブ・バルマー氏は「10年後には社内で運用されるサーバはなくなり、すべてがコンピュータ・クラウドに移行する」とまで発言しています。
実際に、そのようになるかは分かりませんが、GAEを始めとするクラウドは始まったばかりであり、またIT業界で大変関心を持って迎えられているのも確かです。これからの進展が最も興味深い分野の1つでしょう。興味が出た読者は、クラウドをお試しになってはいかがでしょうか。
清野 克行 (せいの かつゆき)
慶應義塾大学工学部電子物理専攻卒。有限会社サイバースペース代表。情報処理学会会員。
日本IBMや日本HPなどにおいて、業務系/基幹業務系システムSE/マーケティングおよび、分散アプリケーション&イントラネットによる社内業務システム開発などに携わる。
現在は、Ajax/クラウド/Web 2.0関連の書籍執筆/セミナー講師/ソフトウェア開発/コンサルティングなどを行っている。
GAEに関しては、9月30日、10月1日に下記内容でのセミナを開催いたします。
「Google App Engine for Java (GAEj) によるクラウドプログラミング講座」。
Copyright © ITmedia, Inc. All Rights Reserved.