JSP自習資料
ホームページを見てTomcatを
インストールしてください
説明では作業ディレクトリを
/export/local/tomcat4.1/webapps/myappとします
適宜読み替えてください
以下のディレクトリがあることを確認してください
% ls -Rd jsp/ servlet/ WEB-INF/ WEB-INF/classes/ WEB-INF/lib/JSPの文法
<%-- --%> 内はコメントです
<%! %> 内は変数/関数宣言です
<% %> 内はJavaのコードです
<%@ page %><%! String message = “Hello, JSP”; %> <html> <body> <p> <% out.println(message); %> </p> </body> </html> ex01.jsp
実行
エディタでmyapp/jsp/ex01.jspを作成します
ブラウザでアドレス欄に以下のように入力します
画面が表示されれば成功です
エラーが出た場合、変換されたソースが
http://localhost:8080/myapp/jsp/ex01.jsp $CATALINA_HOME/work/Standalone/localhost/myapp/jspにできるので参照すること
(; の付け忘れに特に注意)
実習
1
1. ex01.jspの中の2つの;を消してみて
どのようなエラーが発生するか確認せよ
2. 他に()の対応が取れていない場合などの
エラーメッセージを確認せよ
3. <%! %>を<% %>にすると何が起こるか
JSPの変数(1)
以下の変数は宣言なしで使えます(暗黙変数)
request : HTTPの要求 response : HTTPの応答 page : ひとつの要求から応答までの間 session : サーバへの接続から切断までの間 application: アプリケーションの動作中 out : responseの一部, 出力ページ以下は主に内部で使用する変数です
読み出しは構いませんが、書き換えると
JSPが正常動作しなくなることがあるので注意
pageContext: ページに関する情報 confi : 動作環境に関する情報変数の利用
(1)
変数
(クラス)毎にメソッドが定義されてます
別パッケージにあるクラスはimportが必要
<%@ page import = “java.util.*” %> <%! Date d = new Date(); %> <html> <body> <p> Today is <%out.println(d); %>. </p> </body> </html> ex02.jsp
実習
2
ex02.jspのimport宣言を消すとどのような
エラーが出るか確認せよ
ex02.jspを修正して日付と時刻を分けて
2行で表示するようにせよ
(例)
Date is Mon Feb 02 2004.
Time is 12:34:56.
(ヒント: java.text.DateFormatを使用せよ)
変数の利用
(2)
暗黙変数に関するメソッド
String request.getRequestURI() : 呼び出されたURI String request.getServerName() : サーバ名
String request.getServletPort() : ポート番号
String request.getContextType() : 内容を表わすMIME型
<p> URI is <%= request.getRequestURI() %><br> ServerName is <%= request.getServerName() %><br> </p> ex03.jsp(抜粋) <%= 変数 %> は <% out.print(変数) %> と等価
実習
3
ex03.jspを参考に、以下のものを表示する
ページを作成せよ
クライアント情報(getRemoteAddr)
ユーザ情報(getRemoteUser)
言語(getLocale, getCharacterEncoding)
localhost以外からアクセスして確認せよ
変数の利用
(3)
出力関係
response.flushBuffer() : バッファの強制出力 (out.flush()も同じ) response.setContextType(String) : 内容を表わすMIME型 response.setLocale(Locale) : ロケール(言語情報) response.setCharaterEncoding(String) : 文字コード 日本語の出力例(リソース未使用) <% response.setLocale(new Locale(“ja”)); response.setContentType( “text/html; charset=EUC”); %> こんにちは ex04.jsp(抜粋)変数の利用
(4)
セッション関係
String session.getId() : セッションID
boolean session.isNew() : 新しく作成されたか
リロードの場合はfalseになる Object session.getAttribute(String) : 属性参照 Enumuration session.getAttributeNames(): 全属性
void session.setAttribute(String, Object): 属性定義 void session.removeAttribute(String): 属性消去 セッションのタイムアウトはデフォルトで30分 WEB-INF/web.xmlで設定可能(0にしてはいけない!) <session-config> <session-timeout>10</session-timeout> </session-config>
実習
4
ex05.jspはセッションの属性を表示するページである
以下の修正を行い動作を確認せよ
setAttribute/removeAttributeを追加して
属性が保存される様子を確認せよ
session.invalidate()を追加して、新しいセッション
が開始されることを確認せよ
入力
formまたはURLパラメタを利用(?name=val&...)
getParameterで値を参照できるが、
ページ内
に限り有効
他のページで使用する場合はsession変数に保存
<%String name = request.getParameter(“name”); String pass = request.getParameter(“pass”); session.setAttribute(“name”, name);
session.setAttribute(“pass”, encode(pass,key)); %>
ex06.jsp(抜粋)
制御構造
if/else, while, for はJavaと同じ
jsp:forward 出力を破棄して引数のページへ
jsp:include 出力をフラッシュして引数ページへ
終了したら戻ってくる
実習
5
ユーザ名とパスワードを入力の後
正しく登録(ex06)/表示(ex07)が行われるように
制御構造をex08.jspに追加せよ
<form action=“ex08.jsp” >
Username:<input name=“nm” type=“text”><br> Password:<input name=“pw” type=“password”><br> <input type=“submit” value=“login”>
</form> <jsp:??? page=“ex06.jsp”> <jsp:??? /> <jsp:??? /> ex08.jsp(抜粋)
Beanとの連携
ロジック部分はBeanで作成する
JSPからはプロパティを通じてBeanと通信
JSP jsp:useBean Beanを作成, 変数にバインド jsp:setProperty プロパティの値を変更 jsp:getProperty プロパティの値を獲得 順序に注意: Bean作成直後はプロパティはデフォルト値 set get 変更されていたら 値を再計算実習
6
ex09.jsp を実行し動作を確認せよ
loginBean.java はコンパイル後、正しい位置に
配備しないと動作しないので注意せよ
login前の画面では結果を表示しないようにせよ
getPropertyの結果によって次に表示するページを
変更するにはどうしたらよいか?
例外処理
エラー時に表示するページの指定
<%@ page isErrorPage=“true” %> <html> <body> <h2>Error Page</h2> <%= exception.toString() %> occurred.<br> errorPage.jspの内容(抜粋) <%@ page errorPage=“errorPage.jsp” %> 暗黙変数exceptionに例外に関する情報が格納実習
7
ex09.jsp/loginBean.javaを改良して、ユーザ名が
Bean内に登録されていない場合には適切なエラー
ページを表示するようにせよ
入力の保存
ユーザの入力はページ内でのみ有効
他のページに移動した後は再入力必要
sessionに保存してもブラウザ再起動後は無効
sessionを越えた情報保存=cookieの利用 クライアント側に保存/ブラウザによっては使用不可 セキュリティに十分注意することCookie[] request.getCookies() : Cookie一覧を返す void response.addCookie(Cookie) : Cookieを追加 String cookie.getName() : Cookieの名前を返す String cookie.getValue() : Cookieの値を返す
void cookie.setMaxAge(int) : Cookieの有効期限(秒)を設定 0の場合はセッション終了直後に消去
入力の保存
(つづき)
Cookieから値を検索
<% page import=“java.util.*” %>
<%! String getDefault(Cookie[] ck, String key) { if (ck == null) return “”;
for (int i=0;i<ck.length;i++) { if (ck[i].getName().equals(key)) return ck[i].getValue(); } return “”; %> ... <%= getDefault(request.getCookies(), cookieName) %> ex10.jsp(抜粋)
入力の保存
(つづき)
Cookieに値を保存
<%! Cookie c; %><% if (request.getParameter(“nm”) != null) { c = new Cookie(cookieName, request.getParameter(“nm”)); c.setMaxAge(3600); } else { c = new Cookie(cookieName, “”); c.setMaxAge(0); } response.addCookie(c); %> ex10.jsp(抜粋)
実習
8
ex10.jspを実行せよ
(ex09.jspが実行可能であることが前提)
saveをチェックした場合とチェックしない場合での
挙動の違いを確認せよ
別のブラウザ画面からアクセスして動作を確認する
こと
現在はユーザ名を一度保存した後のセッションで
同一ユーザ名でログインした場合でも、saveが
チェックされていないと保存内容が消えてしまう。
これを防ぐようにex10.jspを修正せよ。
パスワードを安全に保存する方法を調査せよ
タグライブラリ
HTML出力とJavaコードが混在
⇒可読性、保守性が低下
使用頻度の高い処理をタグ化
core: 制御構造
fmt: 書式付き出力
xml: XML文書処理
sql: DBアクセス
<% page taglib=“http://java.sun.com/jstl/core” prefix=“c” %> ....
<c:set var=“username” scope=“session” value=“Suzuki” />
Core:変数
変数の記法に注意
<c:set var=“名前” scope=“有効範囲” value=“式” /> 有効範囲: page(デフォルト), request, session, application <c:out value=“式” /> 変数値は ${有効範囲.名前}で参照 有効範囲: pageScope(デフォルト), requestScope ... param, paramValues param.名前 は request.getParameter(名前)と等価 paramValues.[名前]は request.getParameterValues(名前)と等価
Core: 制御構造
Javaと同じ構造が用意されている
<c:if test=“式” >表記</c:if> : if文に相当(elseはない) <c:choose> : switch文に相当
<c:when test=“式1”>表記1</c:when> <c:otherwise>表記n</c:otherwise> </c:choose>
<c:forEach var=“名前” : for文に相当 begin=“式” end=“式” step=“式”>
</c:forEach>
<c:redirect url=“行き先” /> : 行き先に転送(移動) <c:redirect url=“行き先”> パラメタつき
<c:param name=“名前” value=“式”> </c:redirect>
実習
9
ex11.jspを実行せよ
ex06.jspと読みやすさを比較せよ
session.jspの有効範囲をpageとrequestに変更
すると結果がどのように変化するか確認せよ
fmt: 書式つき出力
国際化に対応
<fmt:setLocale value=“ロケール” scope=“有効範囲” /> ロケール: 国コードと言語コード(例: ja_JP)
<fmt:setBundle basename=“名前” var=“コンテキスト名”/> ファイル “名前_ロケール.properties” からリソースを読み込み コンテキストにバインド
username=ユーザ名 password=パスワード
プロパティファイル
<fmt:message key=“名前” bundle=“コンテキスト名” /> コンテキストに基づいた表示
fmt:書式付き出力(つづき)
リソースの作成
username=ユーザ名 password=パスワード EUC*で作成、保存 username=¥uxxxx¥uxxxx... password=¥uxxxx¥uxxxx.... UTF-8に変換 Resources_ja.txt Resources_ja.properties% native2ascii Resources_ja.txt > Resources_ja.properties
/myapp/WEB-INF/classes に配備
(*WindowsではShift-JIS[MS932])
fmt:書式付き出力(つづき)
リソースのバンドルと参照
<%@ page contentType=“text/html; charset=EUC-JP” %> <fmt:setLocale value=“ja” />
<fmt:setBundle basename=“Resources” var=“context” /> <table><tr><td>
<fmt:message key=“username” bundle=“${context}” /> </td><td> ... </td></tr><tr><td>
<fmt:message key=“password” bundle=“${context}” /> </td><td> ... </td></tr>
</table>
実習
10
ex12.jspを実行せよ
リソースの内容を変更し、結果が反映されること
を確認せよ
以下のリソースファイル(を変換したもの)を
読んで反映するようにex12.jsp等を改良せよ
title.top=ログイン画面 title.error=エラー label.username=ユーザ名 label.password=パスワード button.login=ログイン label.error=エラーが発生しましたfmt:書式付出力(つづき)
日付、時刻、数値の出力
<fmt:formatDate value=“時刻” type=“種類” /> 時刻: java.util.Date型変数
種類: time, date, both
pattern= “###0.0#” : 書式指定(数値) “yy/MM/dd HH:mm:ss” : 書式指定(日付) ロケールにより変化 <fmt:formatNumber value=“値” type=“種類” />
種類: number, currency, percent
以下の書式も利用可能
<fmt:formatNumber type=“種類” ... > 表示する値
fmt:書式付き出力(つづき)
可変部をもつメッセージの出力
<fmt:setLocale value=“ja” />
<fmt:setBundle var=“context” basename=“...” /> ... <fmt:message key=“filenotfound” > <fmt:param value=“error.jsp” /> </fmt:message> filenotfound=ファイル {0} がありません Resources_ja.txt ex13.jsp(抜粋) Resources_en.txt filenotfound={0} : No such file.
filenotfound=Aucun fichier {0}. Resources_fr.txt