KEIS BLOGは株式会社ケイズ・ソフトウェアが運営しています。

KEIS BLOG

Google App Engine 第十回

LINEで送る
Pocket

Slim3とは

Slim3とはGoogle App Engine/Javaに最適化されたフルスタックMVCフレームワークです。

Slim3を使ったページの作成方法4

新規コントローラー(ビューなし)の作成

1. build.xmlのAnt Taskからgen-controller-without-viewを右クリック > Run As > 1. Ant Build を選択

2. Ant Input Request [Input a controller path] popup window が開かれます。

misawa01

3. モデルのパスを入力します。
今回は[UpsertController]と[DeleteController]を作成します。
前回とは違いビューが作成されないことに注意してください。

モデルのパスに[memo/upsert]と入力することで下記の2ファイルが自動生成されます。
controller/UpsertController.java
controller/UpsertControllerTest.java

モデルのパスに[memo/upsert]と入力することで下記の2ファイルが自動生成されます。
controller/DeleteController.java
controller/DeleteControllerTest.java

4. 必要なメソッドをコントローラに追加します。
今回は以下の2つのファイルを修正します。

4.1. UpsertController.java
IndexControlle.javaからMemoオブジェクト登録処理を抜出し、
Memoオブジェクト更新しょりを追加する。

package biz.e_zero.slim3_test.controller.memo;

import java.util.Date;

import org.slim3.controller.Controller;
import org.slim3.controller.Navigation;
import org.slim3.datastore.Datastore;
import org.slim3.util.StringUtil;

import biz.e_zero.slim3_test.model.Memo;
import biz.e_zero.slim3_test.service.MemoService;

// IndexControllerからupsert部分を切り出してUpsertControllerを作成(P4)
public class UpsertController extends Controller {

    @Override
    public Navigation run() throws Exception {
        // HTTPリクエストがPOSTかの判断を行い、POSTの場合は登録処理を行う
        if( isPost() ) {
            // MemoServiceのオブジェクトを作成
            MemoService service = new MemoService();
            // Memoオブジェクトを作成
            Memo memo = new Memo();

            // IDを取得してmemoオブジェクトに設定(P4)
            String id = request.getParameter("id");

            // idがブランクの場合処理スキップ
            if (!StringUtil.isEmpty(id)) {
                memo.setKey(Datastore.createKey(Memo.class, Integer.valueOf(id)));
            }
            // Memoオブジェクトに登録用データを設定
            memo.setTitle(request.getParameter("title"));
            memo.setMemo(request.getParameter("memo"));
            memo.setUpdateDate(new Date());

            // MemoServiceにMemoオブジェクトを追加(Upsert)
            service.upsert(memo);
        }

        // IndexControllerにリダイレクト
        return redirect("index");
    }
}

4.1. DeleteController.java
削除処理を作成する。

package biz.e_zero.slim3_test.controller.memo;

import org.slim3.controller.Controller;
import org.slim3.controller.Navigation;
import org.slim3.datastore.Datastore;
import org.slim3.util.StringUtil;

import biz.e_zero.slim3_test.model.Memo;
import biz.e_zero.slim3_test.service.MemoService;

// Controllerを継承してIndexContorollerを作成する。
public class DeleteController extends Controller {

    @Override
    public Navigation run() throws Exception {
        // リクエストパラメータからidを取得
        String id = request.getParameter("id");

        // idがブランクの場合処理スキップ
        if (!StringUtil.isEmpty(id)) {
            // MemoServiceを作成
            MemoService service = new MemoService();
            // 対象idのMemoオブジェクトの削除を行う
            service.delete(Datastore.createKey(Memo.class, Integer.valueOf(id)));
        }
        // IndexContorllerにリダイレクト
        return redirect("index");
    }
}

前回作成ファイルの修正

1. [IndexController.java]の修正
ブラウザキャッシュをOFFにする処理を追加する

package biz.e_zero.slim3_test.controller.memo;

import java.util.List;

import org.slim3.controller.Controller;
import org.slim3.controller.Navigation;

import biz.e_zero.slim3_test.model.Memo;
import biz.e_zero.slim3_test.service.MemoService;

// Controllerを継承してIndexContorollerを作成する。
public class IndexController extends Controller {

    @Override
    public Navigation run() throws Exception {
        // ブラウザキャッシュをOFFにする(P4)
        response.setHeader("Pragma", "no-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 0);
        
        // MemoServiceのオブジェクトを作成
        MemoService service = new MemoService();

        // Memoオブジェクトのリストを取得
        List<Memo> list = service.list();

        // listオブジェクトのスコープを設定
        requestScope("memoList", list);
        // index.jspへリダイレクト
        return forward("index.jsp");
    }
}

2. [index.jsp]の修正

更新(edit)に遷移するためのリンクを作成する。
クエリーパラメータに(id={MemoオブジェクトのID}を追加する。

    <td><a href="edit?id=${f:h(e.key.id)}">${f:h(e.title)}</a></td>

削除(delete)に遷移するためのリンクを作成する。
クエリーパラメータに(id={MemoオブジェクトのID}を追加する。

    <td><a href="delete?id=${f:h(e.key.id)}" class="btn btn-st btn-default">削除</a></td>

index.jsp全体

<%@page pageEncoding="UTF-8" isELIgnored="false" session="false"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn"%>
<%@taglib uri="http://www.slim3.org/functions" prefix="f"%>
<%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<title>Memo List</title>
</head>
<body>
    <h1>Memo</h1>
	<div class="container-fluid">
		<div class="main">
			<div class="table-responsive">
				<table class="table table-striped">
					<thead>
						<tr>
							<th>Title</th>
							<th>Memo</th>
							<th>Update</th>
							<th>Delete</th>
						</tr>
					</thead>
					<tbody>
						<c:forEach var="e" items="${memoList}">
							<tr>
								<td><a href="edit?id=${f:h(e.key.id)}">${f:h(e.title)}</a></td>
								<td>${f:h(e.memo)}</td>
								<td>${f:h(e.updateDate)}</td>
								<td><a href="delete?id=${f:h(e.key.id)}" class="btn btn-st btn-default">削除</a></td>
							</tr>
						</c:forEach>
					</tbody>
				</table>
			</div>
			<a href="edit" class="btn btn-lg btn-default">追加</a>
		</div>
	</div>
</body>
</html>

3. [EditController.java]の修正
前回の新規作成時の処理に変更時の処理を追加する。

package biz.e_zero.slim3_test.controller.memo;

import org.slim3.controller.Controller;
import org.slim3.controller.Navigation;
import org.slim3.datastore.Datastore;
import org.slim3.util.StringUtil;

import com.google.appengine.api.datastore.Key;

import biz.e_zero.slim3_test.model.Memo;
import biz.e_zero.slim3_test.service.MemoService;

//Controllerを継承してEditContorollerを作成する。
public class EditController extends Controller {
    @Override
    public Navigation run() throws Exception {
        // リクエストパラメータからidを取得
        String id  = request.getParameter("id");

        Memo memo = null;

        // 新規作成 or 変更の分岐(P4)
        if (StringUtil.isEmpty(id)) {
            // idがnullまたは空白だった場合は新規作成
            // memoオブジェクトを新規作成
            memo = new Memo();
        } else {
            // それ以外は変更(P4)
            // MemoServiceを作成(P4)
            MemoService service = new MemoService();

            // idからMemoクラス用のKeyオブジェクトを作成(P4)
            Key key = Datastore.createKey(Memo.class, Integer.valueOf(id));
            // keyに一致するmemoオブジェクトを取得(P4)
            memo = service.get(key);
        }     

        // memoオブジェクトのスコープを設定
        requestScope("memo", memo);  
        
        // edit.jspへフォワード
        return forward("edit.jsp");
    }
}

4. [edit.jsp]の修正
入力項目の初期値を設定する(value)
idをhidden項目に設定する

	<input type="text" name="title" value="${f:h(memo.title)}" class="form-control" placeholder="Title">
        :
	<input type="text" name="memo" value="${f:h(memo.memo)}" class="form-control" placeholder="Memo">
        :
	<input type="hidden" name="id" value="${f:h(memo.key.id)}">

edit.jsp全体

<%@page pageEncoding="UTF-8" isELIgnored="false" session="false"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>
<%@taglib prefix="f" uri="http://www.slim3.org/functions"%>

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<title>memo Edit</title>
</head>
<body>
    <div class="container">
		<h2>Memo Edit</h2>
		<form method="post" action="/memo/upsert" class="form-horizontal">
			<div class="form-group">
				<label class="col-sm-2 control-label">タイトル</label>
				<div class="col-sm-10">
					<input type="text" name="title" value="${f:h(memo.title)}" class="form-control" placeholder="Title">
				</div>
			</div>
			<div class="form-group">
				<label class="col-sm-2 control-label">メモ</label>
				<div class="col-sm-10">
					<input type="text" name="memo" value="${f:h(memo.memo)}" class="form-control" placeholder="Memo">
				</div>
			</div>
			<div class="form-group">
				<div class="col-sm-offset-2 col-sm-10">
					<input type="submit" class="btn btn-default" /> <a href="index" class="btn btn-primary">戻る</a>
					<input type="hidden" name="id" value="${f:h(memo.key.id)}">
				</div>
			</div>
		</form>
	</div>
</body>
</html>

アプリケーションの動作確認

1. プロジェクトトップを右クリック > Debug As > x. Web Applicationを選択
Consoleにアプリケーション起動状況が表示されます。

2. ブラウザからURLを入力して動作確認を行います。
URL: http://localhost:8888/memo/

misawa02
3. リスト画面が表示される
前回登録済みのデータが表示されます。
リストのタイトルリンクをクリックして登録画面へ遷移します。

misawa03
4. 登録画面が表示される
選択されたMemoオブジェクトの内容が表示されます。
[送信]ボタンを押すことで変更した内容をDatastoreに登録します。
[戻る]ボタンで編集内容を破棄してリスト画面に戻ります。

misawa04
5. リスト画面に遷移する
リスト表示画面に変更されたMemoオブジェクトが表示されます。

misawa05
6. Memoオブジェクトの削除
[追加]ボタンから適当なMemoオブジェクトを作成します。
サンプルでは”削除してください!”というMemoオブジェクトを作成しています。
右端の[削除]ボタンを押してMemoオブジェクトを削除します。

misawa06
7. 削除完了
無事削除されました。
※このサンプルでは削除確認などの実装ありません。

次回は「Slim3を使ったページの作成方法5」をご紹介します。

【関連記事】
Google App Engine 第一回
Google App Engine 第二回
Javaのライブラリを手軽にテストしたい!! Groovy入門 第1回
Google App Engine 第三回
Google App Engine 第四回
Google App Engine 第五回
Google App Engine 第六回
Google App Engine 第七回
Google App Engine 第八回
Google App Engine 第九回

LINEで送る
Pocket