データベースシステム特論
Web
プログラミングの種類
•
クライアントサイドで動作
–
JavaScript
–
Java Applet
–
Flash ActionScript
•
サーバサイドで動作
–
CGI (C, perl, ruby
等
)
–
PHP
–
Servlet
,
JSP
(JavaServer Pages)
Servlet
•
サーバサイドで動作する
Java
プログラム
•
リクエスト毎に新しいスレッドで処理する
–
CGI
が通常新しいプロセスを立ち上げるのに比べ
て軽い
–
セッション管理等の継続処理が容易
• Tomcat
あるいは
Apache+Tomcat
でサーバを容易
に構築できる
• JSP
により動的な
Web
ページを容易に作成できる
–
HTML
記述中に
Java
プログラム記述を埋め込む
• Java
のセキュリティ機能によるチェックが可能
•
一つの
Servlet
の動作の不具合が,コンテナ
(
サーバ
)
全体に影響する
Servlet
の作成
• $CATALINA HOME/webapps/tomcat-docs/appdev/
sample
をディレクトリごと適当な場所にコピー
• Ant
で
build
するための追加設定ファイルである
build.properties
を作成
app.name=myapp
app.version=0.1-dev
catalina.home=/usr/local/lib/tomcat5
manager.username=XXX
manager.password=YYY
• Tomcat
をスタート
• ant install
を実行
• http://localhost:8080/myapp
にアクセス
Ant
の使い方
• build.xml
が設定ファイル,
build.properties
が追加
設定ファイル
• Unix
の
make
と同様に,依存関係を調べてファイル
の再コンパイル等を行ってくれる
•
実行例
$ ant compile
#
コンパイルの実行
$ ant javadoc
# Javadoc
の作成
$ ant dist
#
配布用
war
ファイルの作成
$ ant clean
#
ファイル置場
build, dist
の削除
$ ant install
# Tomcat
への
deploy (
インストール
)
$ ant reload
# Tomcat
への再
deploy
sample
の内容
sample/
+- index.html 説明ファイル (不要) +- sample.war war ファイル (不要)
+- build.xml Ant での build のための設定ファイル
+- build.properties Ant での build のための追加設定ファイル +- docs/ ドキュメント置場 | +- README.txt 説明ファイル (ファイル名は何でも良い) +- src/ ソース置場 | +- mypackage/ パッケージ名 | +- Hello.java サーブレットプログラム +- web/ 設定ファイル,HTML, JSP ファイル等 | +- WEB-INF/ 設定ファイル置場 | | +- web.xml サーブレットの設定ファイル | +- index.html HTML ファイル | +- hello.jsp JSP ファイル | +- images/ イメージファイル置場
+- build/ ant compile 時に作成されるファイル置場 +- dist/ ant dist 時に作成されるファイル置場
+- docs/ ドキュメント,Javadoc ファイル置場
web.xml
の内容
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" ...> <!-- 説明 -->
<display-name>Hello, World Application</display-name> <description>
This is a simple web application with a source code organization based on the recommendations of the Application Developer’s Guide. </description>
<!-- Servlet 名とクラスの指定 --> <servlet>
<servlet-name>HelloServlet</servlet-name>
<servlet-class>mypackage.Hello</servlet-class> </servlet>
<!-- Servlet の URL を指定 --> <servlet-mapping>
<servlet-name>HelloServlet</servlet-name> <url-pattern>/hello</url-pattern>
</servlet-mapping> </web-app>
Hello.java
の内容
public final class Hello extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
response.setContentType("text/html");
PrintWriter writer = response.getWriter(); ... } }
• Hello
クラスのオブジェクトは,
/myapp/hello
に初
めてアクセスがあった時のみに作成される
•
リクエストのたびに,
HttpServletRequest
および
HttpServletResponse
のオブジェクト,新しいスレッ
ドが生成され,
Hello
クラスのメソッドが呼び出される
–
GET
リクエストの場合,
doGet
メソッド
–
POST
リクエストの場合,
doPost
メソッド
(
この
プログラム例には含まれていない
)
日本語処理の例
sample2/ +- build.xml 元のまま +- build.properties 変更 +- docs/ | +- README.txt (削除しても良い) +- src/ | +- mypackage/ パッケージ名 | +- ShowParams.java 作成 +- web/ +- WEB-INF/ | +- web.xml 変更 +- index.html 作成 +- showparams.jsp 作成 (次回説明) +- manager/ 作成 +- index.html 作成• sample
を
sample2
に変更
•
その他のファイルは,必要ないので削除
build.properties
と
web.xml
の変更点
• build.properties
app.name=myapp2 app.version=0.1 catalina.home=/usr/local/lib/tomcat5 manager.username=XXX manager.password=YYY• web.xml
<servlet><servlet-name>ShowParams</servlet-name>
<servlet-class>mypackage.ShowParams</servlet-class> </servlet>
<servlet-mapping>
<servlet-name>ShowParams</servlet-name> <url-pattern>/showparams</url-pattern> </servlet-mapping>
index.html
の内容
<h1>GET メソッド</h1>
<form method="GET" action="showparams"> <dl>
<dd>param1 <input name="param1" type="text"> <dd>param2 <input name="param2" type="text"> <dd><input type="submit" value="Submit">
</dl> </form>
<h1>POST メソッド</h1>
<form method="POST" action="showparams"> <dl>
<dd>param1 <input name="param1" type="text"> <dd>param2 <input name="param2" type="text"> <dd><input type="submit" value="Submit">
</dl> </form>
ShowParams.java
の内容
package mypackage;
int accessCounter = 0;
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
// 出力形式,出力文字コードを指定
response.setContentType("text/html; charset=Shift_JIS"); PrintWriter out = response.getWriter();
// アクセスカウンターをインクリメント accessCounter++; ... // リクエストメソッド等を表示 showRequest(out, request); ... // リクエストヘッダの内容を表示 showHeaders(out, request); ... // フォームのパラメータの内容を表示 // 送信されてくる文字がシフト JIS でエンコードされている場合
showParameters(out, request, "Shift_JIS"); ...
ShowParams.java
の内容
(
続き
)
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
doGet(request, response);
}
ShowParams.java
の内容
(
続き
)
public static void showRequest(PrintWriter out, HttpServletRequest request)
{
out.println("<li>Method : " + request.getMethod());
out.println("<li>Request URI : " + request.getRequestURI()); out.println("<li>Protocol : " + request.getProtocol());
out.println("<li>PathInfo : " + request.getPathInfo());
out.println("<li>Remote Address : " + request.getRemoteAddr());
}
ShowParams.java
の内容
(
続き
)
public static void showHeaders(PrintWriter out, HttpServletRequest request)
{
out.println("<ul>");
Enumeration e = request.getHeaderNames(); while (e.hasMoreElements()) {
String name = (String)e.nextElement(); String value = request.getHeader(name);
out.println("<li>" + htmlEncode(name) + " : " + htmlEncode(value));
}
out.println("</ul>");
}
ShowParams.java
の内容
(
続き
)
public static void showParameters(PrintWriter out,
HttpServletRequest request, String encoding) { out.println("<ul>");
Enumeration e = request.getParameterNames(); while (e.hasMoreElements()) {
String name = (String)e.nextElement();
String value = request.getParameter(name); value = decodeParameter(value, encoding);
out.println("<li>" + htmlEncode(name) + " : " + htmlEncode(value));
}
out.println("</ul>");
}
ShowParams.java
の内容
(
続き
)
public static String decodeParameter(String param, String encoding) { if (param == null || param.equals(""))
return param; try {
param = new String(param.getBytes("iso-8859-1"), encoding);
} catch (UnsupportedEncodingException e) { } return param; }
• decodeParameter
は,渡されたパラメータが
encod-ing
で指定された文字コードでエンコーディングさ
れているとして,
Unicode
に変換する
(encoding
が
JISAutoDetect
なら自動判別
)
• request.setCharacterEncoding("Shift JIS")
は,
GET
メソッドの場合に正しく動作しないので,上の
様にする
ShowParams.java
の内容
(
続き
)
public static String htmlEncode(String str) { return str .replaceAll("[\\x00-\\x1f]", " ") .replaceAll("&", "&") .replaceAll("<", "<") .replaceAll(">", ">") .replaceAll("\"", """); }
• htmlEncode
は文字列をサニタイジング
(
無害化
)
する
セッション管理の例
•
セッション
(session)
–
同一ブラウザからの一連のアクセス
•
サーバが生成したセッション
ID
と呼ばれる文字列を
ブラウザがクッキーとして保存
(
有効期限はブラウザ
を閉じるまで
)
•
サーバはセッション
ID
と結びつけて様々な情報を記
憶することで,同一セッション中の複数のページ間に
またがる情報を管理
•
買い物カゴなどに利用
セッション管理の例
(
続き
)
買い物カゴへの追加の例
// セッションの取得,あるいはセッションの生成
HttpSession session = request.getSession(true); // 買い物カゴ情報を取得
Vector cart = (Vector)session.getAttribute("cart"); // 買い物カゴが存在していなければ,空の買い物カゴを生成
if (cart == null) {
cart = new Vector();
}
// 買い物カゴに追加
String item = request.getParameter("item"); cart.add(item);
// 買い物カゴをセッション情報として保存
属性とスコープ
• setAttribute, getAttribute
メソッドで,様々な
スコー
プ
に対して有効な値
(
任意のオブジェクト
)
を
属性
とし
て設定
/
利用できる
• JSP
の
EL
式を用いて,
Servlet
と
JSP
間で値を受渡
しできる
•
スコープ
–
リクエスト
:
同一リクエスト内
(forward
した先の
ページでも良い
)
–
セッション
:
同一セッション内
–
ア プ リ ケ ー ション
:
同 一 ア プ リ ケ ー ション 内
(ServletContext
オブジェクト
)
Tomcat
でのユーザ認証
•
認証方法としては,
Basic
認証,
Digest
認証以外に,
Web
開発者の用意したフォームを利用する
Form
認
証,
SSL
クライアント認証も利用可能
• ID
とパスワードのデータベース
(
レルム
, realm)
とし
ては以下が利用可能
–
メモリレルム
: conf/tomcat-users.xml
を利用
–
JDBC
レルム
: JDBC
により
RDB
を利用
–
JNDI
レルム
: LDAP
サーバを利用
Tomcat
での
Basic/Digest
認証の例
• WEB-INF/web.xml
に以下の記述を追加
<security-constraint>
<web-resource-collection>
<web-resource-name>Manager pages</web-resource-name>
<url-pattern>/manager/*</url-pattern> <!-- 認証の必要なパスを指定 --> </web-resource-collection>
<auth-constraint>
<role-name>manager</role-name> <!-- role の指定 --> </auth-constraint>
</security-constraint> <login-config>
<auth-method>BASIC</auth-method> <!-- Digest 認証なら DIGEST --> <realm-name>Manager pages</realm-name>
</login-config> <security-role>
<role-name>manager</role-name> </security-role>
Tomcat
での
Form
認証の例
• WEB-INF/web.xml
に 以 下 の 記 述 を 追 加
(login-config
部分のみ
)
• login.jsp
はログイン画面
• error.jsp
は認証エラーの画面
<login-config><auth-method>FORM</auth-method>
<realm-name>Manager pages</realm-name> <form-login-config> <form-login-page>/login.jsp</form-login-page> <form-error-page>/error.jsp</form-error-page> </form-login-config> </login-config>
Tomcat
での
Form
認証の例
(
続き
)
• login.jsp
の内容例
<%@ page language="java" contentType="text/html; charset=Shift_JIS" %> <html>
<head>
<title>login</title> </head>
<body>
<form method="POST" action=’<%= response.encodeURL("j_security_check") %>’> <ul>
<li>ユーザ ID <input type="text" name="j_username">
<li>パスワード <input type="password" name="j_password"> <li><input type="submit" value="Login">
</ul> </form> </body> </html>