とりあえず雑記帳(跡地)
Controllerで画面作成
最終更新:
fujiyan
-
view
Controllerとはなんぞや
- Controllerは、「Slim3としては」URLに関連付けられたアクションであり、ブラウザ等からそのURLでリクエストが送られた際に実行されます。
- 通常は、Controllerで処理が実行された後、その結果をjspで出力します。
- ということで、Controllerを作成する際には、通常はControllerクラスとjspのセットで作成します。
- 「Slim3としては」という但し書きをしましたが、一般論としてのControllerの役割も勿論あります(そのうち説明の予定)。
- URLのパス階層と、Controllerのサブパッケージ階層が対応するように作成します。
- クラス名は、URLのパス階層の末尾(先頭は大文字)+Controllerとします。
- URLのパス階層の末尾がスラッシュで終わる場合は、IndexControllerとします。
- [Root Package]がjp.fujiyan.booklistの場合
リクエストのURL | 必要なController |
/ | jp.fujiyan.booklist.controller.IndexController |
/show | jp.fujiyan.booklist.controller.ShowController |
/sub/ | jp.fujiyan.booklist.controller.sub.IndexController |
/sub/show | jp.fujiyan.booklist.controller.sub.ShowController |
一覧画面のControllerを作成する
- 一覧画面を基点にして、登録/変更画面に遷移するので、まずは一覧画面を作成してみましょう。
- Modelの作成時にも利用した、build.xmlから[gen-controller]targetを実行します。
- ダイアログが表示されるので、作成するControllerに対応するURLパスを入力します。
- 今回は/book/showBookListというURLを入力します。
- すると、jp.fujiyan.booklist.controller.book.ShowBookListControllerというクラスと、/war/book/showBookList.jspというjspファイルが生成されます。
package jp.fujiyan.booklist.controller.book;
import org.slim3.controller.Controller;
import org.slim3.controller.Navigation;
public class ShowBookListController extends Controller {
@Override
public Navigation run() throws Exception {
return forward("showBookList.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" />
<title>book ShowBookList</title>
</head>
<body>
<p>Hello book ShowBookList !!!</p>
</body>
</html>
詳細画面のControllerを作成する
- とはいえ、登録が出来なければ一覧表示も出来ないので、詳細画面も作成して、一覧画面から遷移するようにしましょう。
- もう一度、build.xmlから[gen-controller]targetを実行します。
- ダイアログが表示されるので、作成するControllerに対応するURLパスを入力します。
- 今回は/book/showBookDetailというURLを入力します。
- すると、jp.fujiyan.booklist.controller.book.ShowBookDetailControllerというクラスと、/war/book/showBookDetail.jspというjspファイルが生成されます。
package jp.fujiyan.booklist.controller.book;
import org.slim3.controller.Controller;
import org.slim3.controller.Navigation;
public class ShowBookDetailController extends Controller {
@Override
public Navigation run() throws Exception {
return forward("showBookDetail.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" />
<title>book ShowBookDetail</title>
</head>
<body>
<p>Hello book ShowBookDetail !!!</p>
</body>
</html>
まぁ、とりあえず表示してみましょう。
- 実行するには、プロジェクトを選択しておいて、メニューの[Run]-[Debug As]-[Web Application]を選択します。
- デフォルトの設定なら、8888ポートでアクセスできます。
- まずは一覧画面。Controller作成時に入力したパス、/book/showBookListを指定します。
- 続いて詳細画面。やはりController作成時に入力したパス、/book/showBookDetaliを指定します。
一覧画面に新規登録リンクを設置
- まずは、showBookList.jspを修正して、詳細画面へ新規登録モードで遷移するための「新規登録」リンクを設置します。
- リンクのURLの生成に、Slim3が提供しているJSP Functionである、url()を用いています。
- url()は引数で指定したリソースへの、コンテキスト相対パスを生成します。
- 例えば、/book/showBookListで生成されるJSPでurl('test')と指定すると、"/book/test"というURLが生成されます。
- 今回は、詳細画面のControllerである、/book/showBookDetailを指すので、url()には'showBookDetail'を指定します。
- ついでなんで、titleも変えときましょう。
生成されたHTMLソース
詳細画面に入力フォームを設置
- つぎは、showBookDetail.jspを修正して、詳細画面に入力フォームを設置します。
- 今のところは、只のHTML/JavaScriptの内容です。
<%@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" />
<title>本詳細</title>
</head>
<body>
<form>
<table>
<tr>
<th>作品名</th><td><input type="text" size="80"/></td>
</tr>
</table>
<input type="submit" value="更新" onclick="return confirm('更新しますか?');"/>
<input type="button" value="戻る" onclick="history.back();"/>
</form>
</body>
</html>
更新機能の実装の前に…、ちょっとSlim3を離れてWebアプリケーション一般論
- HTTPでのリクエストには主にGETメソッドとPOSTメソッドがあります(それ以外は、まぁ使いません)。
- どっちも、リクエストを与えるとレスポンスが返ってくる、という点で同じ動きではありますが、意味合いが違います。
- なので、Webアプリケーションでは、両者を「正しく」使い分けることが重要です。
- GETは「情報を取得する」メソッドで、POSTは「情報を送信する」メソッドです。この違いは、キャッシュが無効になってしまったときに現れます。
- GETメソッドの場合は、再びGETメソッドで取得します。見た目上は、キャッシュの有効時/無効時ではあまり違いが無いです。
- 一方POSTメソッドの場合は、キャッシュが無効な場合は、レスポンスの取得のため、再び情報を送信しようとします。
- ブラウザの「戻る」ボタンで、フォームデータ送信等のPOSTメソッドのリクエストまで戻ると、「フォームデータの再送信がうんたらかんたら」が出るのはそのためです。
- POSTメソッドのレスポンスは、リダイレクトでGETメソッドに挿げ替えることによって、「戻る」ボタンで戻っても「再送信うんたら」は出なくなります。
- ということで、POSTメソッドは出来るだけリダイレクトでGETメソッドに挿げ替え、履歴上を極力GETメソッドだけにしてしまいましょう。
- そうすれば「戻る」ボタンで自由に戻れるWebアプリケーションになります。
- よく「戻る」ボタンは敵視されることもありますが、「Web」アプリケーションなのですから、「戻る」ボタンを生かすように努めましょう。
- とは言え「戻る」ボタンで戻った当時の状態を再現せよ、というわけではないですよ。データ更新後に、「戻る」で戻った場合に更新後の情報が表示されるのは、まぁ良しじゃないでしょうか。
前置きはコレくらいにして、更新Controllerを作成する
- さて、入力フォームのsubmit先となる、更新Controllerを作成します。
- 更新処理はPOSTメソッドでリクエストし、その後一覧画面Controllerにリダイレクトするようにします。
- よって、更新ControllerのJSPは不要です。
- JSPを伴わないControllerを作成する場合は、build.xmlから[gen-controller-without-view]targetを実行します。
- ダイアログが表示されるので、作成するControllerに対応するURLパスを入力します。
- 今回は/book/putBookというURLを入力します。
- すると、jp.fujiyan.booklist.controller.book.PutBookControllerというクラスが生成されます。
package jp.fujiyan.booklist.controller.book;
import org.slim3.controller.Controller;
import org.slim3.controller.Navigation;
public class PutBookController extends Controller {
@Override
public Navigation run() throws Exception {
return null;
}
}
- 実際の更新処理を実装する前に、処理後に一覧画面Controllerにリダイレクトするようにしてみましょう。
- リダイレクトさせるには、redirect()メソッドにリダイレクト先を指定して、戻り値のNavigationをrun()の戻り値にします。
public class PutBookController extends Controller {
@Override
public Navigation run() throws Exception {
return redirect("showBookList");
}
}
- あと、入力フォームのsubmit先に更新Controllerを指定します。
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>本詳細</title>
</head>
<body>
<form action="putBook" method="POST">
<table>
<tr>
<th>作品名</th><td><input type="text" size="80"/></td>
</tr>
</table>
<input type="submit" value="更新" onclick="return confirm('更新しますか?');"/>
<input type="button" value="戻る" onclick="history.back();"/>
</form>
</body>
</html>