設定が完了したら、アプリケーションを実装していきましょう。最初に、Webブラウザのリクエストを受け付けるアクションを記述します。ここでは、単にブログの画面(blog.gt)を表示するだけのスクリプトを作成します。
request.view = 'blog.gt'; zero.core.views.ViewEngine.render();
アプリケーションによっては、表示画面を遷移させますが、遷移などはアクションで制御します。
Webブラウザに表示するブログの画面を作成します。投稿ボタンで記事を投稿し、削除ボタンで記事を削除します。ここでは、Dojoライブラリを利用して、サーバと通信し、ブログの記事一覧の取得、記事の追加、削除を行うようにしています。
<html> <head> <title>Blogタイトル</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <script type="text/javascript" src="/dojo.js"></script> <script type="text/javascript"> dojo.require("dojo.io.*"); dojo.require("dojo.widget.TitlePane"); dojo.hostenv.writeIncludes(); // 記事の追加 function addArticle() { var data = { title: document.blogForm.title.value, body: document.blogForm.body.value }; dojo.io.bind({ url: '/resources/blog', method: "POST", headers: { 'X-Method-Override' : 'POST' }, mimetype: "text/json", sync: true, content: data }); document.blogForm.reset(); getArticles(); } // 記事の削除 function deleteArticles() { var list = document.blogForm; for (var i=0; i<list.length; i++) { if (list[i].checked) { // チェックされた記事を削除 dojo.io.bind({ url: '/resources/blog/'+list[i].value, method: "POST", headers: { 'X-Method-Override' : 'DELETE' }, mimetype: "text/json", sync: true }); } } getArticles(); } // 記事の表示 function getArticles(){ dojo.io.bind({ handler: getArticleCallback, url: '/resources/blog', method: "GET", mimetype: "text/json"}); } // 記事表示の通信実行中に呼び出すコールバック関数 function getArticleCallback(type, data, evt) { var list = ""; if (type == 'error') alert('サーバ信中にエラーが発生しました'); else if (data != null) for (var i=0; i<data.length; i++) { list += '<hr />' + '<div id="del"' + 'style="float:right;width:100px;">' + '<input type="checkbox" name="posts" value="' + data[i].id + '">削除</div><b>' + data[i].title + ' </b><br><pre>' + data[i].body + '</pre>'; } document.getElementById("articleList").innerHTML = list; } // HTML読み込み時に記事を表示 window.onload = function() { getArticles(); } </script> </head> <body> <h1>シンプルブログ:</h1> <form name="blogForm"> <!-- 記事の表示領域 --> <div id="articleList"></div> <hr> タイトル:<br /> <input type="text" id="title"><br> 本文:<br> <textarea cols="50" name="body"></textarea><br> <input type="button" onClick="addArticle()" value="投稿"> <input type="button" onClick="deleteArticles()" value="削除"> </form> </body> </html>
ブラウザのJavaScriptから送信されたデータを処理し、レスポンスを返却するリソースを作成します(リスト5)。
// 記事返却 //def onGET() { def onList() { sendJSONData(zero.data.Manager.create('blog')); } // 記事投稿 def onCreate() { def title = request.params.title[0].get(); def body = request.params.body[0].get(); if (title != null && title.size() > 0) { def dm = zero.data.groovy.Manager.create('blog'); def id = dm.insert( "INSERT INTO blog (title, body) VALUES ($title, $body)" ,['id']); request.status = HttpURLConnection.HTTP_CREATED; request.headers.out.Location=request.status.get() + '/' + id sendJSONData(dm); } else { request.status = HttpURLConnection.HTTP_NO_CONTENT; } } // 記事削除 def onDelete() { def id = request.params.blogId[0].get(); if (id != null) { def dm = zero.data.Manager.create('blog'); dm.update("DELETE FROM blog WHERE id = $id"); sendJSONData(dm); } } def sendJSONData(dm) { def data = dm.queryList("SELECT id, title, body FROM blog"); request.headers.out."Content-Type"="application/json" request.view="JSON"; request.json.output = data; zero.core.views.ViewEngine.render(); }
リスト5では、記事のリストの返却(onListメソッド)、記事の投稿(onCreateメソッド)、記事の削除(onDeleteメソッド)を行います。
RoR(Ruby on Rails)がO/Rマッピングを利用するのに対し、ZeroはSQLを直接書いて実行結果をハッシュに格納します。DBを隠ぺいするRoRに比べ、SQLに慣れた開発者の場合、Zeroの方が直感的に何をしているのか分かりやすいという利点があります。
Zeroアプリケーションを実行するには、Zeroプロジェクトを右クリックして、[実行]→[Project Zero Application]を選択します。アクションのURL「http://localhost:8080/blog.groovyにアクセスすると、図4のブログが表示されます。
簡単にProject ZeroのJava版について紹介してきました。StrutsやJSFに比べ、Groovyを使った簡易的な構文でアクション/テンプレートが記述できたり、Ajaxを積極的にサポートしている点が特徴となっています。
なお、本稿では紹介できませんでしたが、フロー(処理の流れ)を記述するツールも開発されています(図7)。
Project Zero自身はまだまだ発展途上でありますが、十分今後の展開に期待が持てる内容になっていると思います。ただ、Project Zero自身はIBMお得意のオープンソースではなく、今後のライセンスの扱いに懸念が残るところですが、今後の動向に注目したいと思います。
Copyright © ITmedia, Inc. All Rights Reserved.