検索
連載

Project Zeroでスクリプト+Ajaxのアジャイル開発CoolなEclipseプラグイン(19)(3/3 ページ)

PC用表示 関連情報
Share
Tweet
LINE
Hatena
前のページへ |       

アクションの作成

 設定が完了したら、アプリケーションを実装していきましょう。最初に、Webブラウザのリクエストを受け付けるアクションを記述します。ここでは、単にブログの画面(blog.gt)を表示するだけのスクリプトを作成します。

request.view = 'blog.gt';
zero.core.views.ViewEngine.render();
リスト3 public/blog.groovy

 アプリケーションによっては、表示画面を遷移させますが、遷移などはアクションで制御します。

ビューの作成

 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>
リスト4 app/views/blog.gt

リソースの作成

 ブラウザの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 app/resources/blog.groovy

 リスト5では、記事のリストの返却(onListメソッド)、記事の投稿(onCreateメソッド)、記事の削除(onDeleteメソッド)を行います。

 RoRRuby on Rails)がO/Rマッピングを利用するのに対し、ZeroはSQLを直接書いて実行結果をハッシュに格納します。DBを隠ぺいするRoRに比べ、SQLに慣れた開発者の場合、Zeroの方が直感的に何をしているのか分かりやすいという利点があります。

Zeroアプリケーションを実行してみると……

 Zeroアプリケーションを実行するには、Zeroプロジェクトを右クリックして、[実行]→[Project Zero Application]を選択します。アクションのURL「http://localhost:8080/blog.groovyにアクセスすると、図4のブログが表示されます。

発展途上中のProject Zeroに期待

 簡単にProject ZeroのJava版について紹介してきました。StrutsJSFに比べ、Groovyを使った簡易的な構文でアクション/テンプレートが記述できたり、Ajaxを積極的にサポートしている点が特徴となっています。

 なお、本稿では紹介できませんでしたが、フロー(処理の流れ)を記述するツールも開発されています(図7)。

図7 Project Zeroの画面遷移を記述するツール
図7 Project Zeroの、フロー(処理の流れ)を記述するツール

 Project Zero自身はまだまだ発展途上でありますが、十分今後の展開に期待が持てる内容になっていると思います。ただ、Project Zero自身はIBMお得意のオープンソースではなく、今後のライセンスの扱いに懸念が残るところですが、今後の動向に注目したいと思います。


Copyright © ITmedia, Inc. All Rights Reserved.

前のページへ |       
ページトップに戻る