ウエブアプリケーション
JSP その1
2017/12/21
海谷 治彦
1
http://www0.info.kanagawa-u.ac.jp/~kaiya/wa/
dotcampus ショートコード 212834
目次
• 復習 サーバーサイド技術 サーバーとの相互作用
• JSPとServlet 違いや共通点
• JSPの基礎
• JSPにおける response/requestの操作
• 演習
2
サーバーサイドの主な役割
• 検索,計算,データ保存や共有,手順のナビゲー
ト,画面データの生成等
3
データ 検索 計算 生成 送受信 保存復習
+
サーバーサイドの具体的技術
• JavaによるJSP/Servlet
• 銀行系等の大規模で信頼性の必要なシステム向け.
• PHP
• お手軽にサイトを作るサーバーサイド言語.
• Cに似ている.
• Ruby on Rails
• 最も有名なモダンフレームワーク
• 伝統的なCGI (Common Gateway Interface)
• Perl, Ruby, C等でサーバー側処理をするもの.
• いまどきは見かけない.
4
データの保持
• 業務や娯楽等を継続的に利用するため,クライア
ントサイド,サーバーサイドそれぞれにデータを保
持する機能がある.
• クライアントサイド
• クッキー
• ウエブストレージ
• サーバーサイド
• サーバーOSのファイルにデータを直に読み書き
• いまどきは,あまり行わない.
• データベースを利用
5
復習
データ保持の例
• 一連の処理(セッション)の識別
• 過去の行動を保持
• たとえば閲覧した商品のリスト等
• 作業途中のデータ保存
• 例えばゲームにおける艦隊構成や武装
• 作業履歴
• 購入した商品のリスト
• 共同作業データの共有
• 個人に紐付けされたデータの保持
• クレジットカード番号,ポイントの残高等
6
復習
+
サーバーと対話
• HTTPリクエスト/レスポンスは複数回行われる.
• 無論,JSも使えるが.
• サーバー側のデータが使えるので,例えば,端末
を変えても処理が継続できる.
• 途中まで大学でやって,あとは家のPCでやるとか.
7
ブラウザ JSプログラム ・ ・ ・ ・ ・ 入力画面準備 選択肢を送る 結果が返ってくる サーバー 側のデータ サーバー プログラム web storage等復習
--サーバーとの対話
• ユーザーの入力手段
• form というタグを用いて,受け取りページを指定して,
自身の入力情報とともにHTTPリクエストを送る.
• 無論,受け取りページは処理能力がなければいけない.
(通常,PHPやServletで書かれる)
• 出力手段
• 受け取りページに結果が埋め込まれた形で,HTTPレ
スポンスが返ってくる.
• その結果をブラウザが表示する.
• 入力したページとは別のページに移動していることを注
意.(ページ遷移と呼ばれる)
• サーバーもクライアントも一連のページであるという情報を(細
工無しでは)もっていない.
8
復習
Formの典型様式
9
<form action="
http://www.example.com/form.php
" method="
post
">
Topic:
<
input type="text"
name="topic" size="20">
<br>
<textarea rows="5" cols="22" name="feedback">
</textarea>
<br>
<
input type="submit"
value="send">
</form>
メッセージを受け取るページを 指定.このページはリクエスト処 理の能力がないといけない. get もしくは post を指定. 違いは後述. ユーザーの入力値を最 終的に受け取りページ に送るための呪文. ユーザー入力場所の指 定.詳細は後述. ユーザー入力場所の指 定.詳細は後述.復習
GETとPOST
• GET
• 本来はサーバーからのデータ取得リクエストに用いる.
• よって,クライアント側から原則データを送ることはできない.
• しかし,URL自体にデータを付記することで,データを無理
やり送ることが可能となっている.
• 送ったデータはURLを見ただけで丸見え.
• POST
• サーバーにデータを送る本来のリクエスト.
• リクエストの本体(ヘッダーより下)に送るデータが付記される.
• 一応,ぱっと見にはデータは見えないが,暗号化されていな
いHTTPは簡単に傍受できるので,実際にはデータは丸見え.
10
復習
クライアントからデータを送る
• POSTを使えば任意のデータをサーバーに送れる.
• しかし,パラメータ名と値の対として,データを送る
のが一般的.(一般にkey-valueデータと呼ばれる)
• 以下の arg1 と arg2 がそれぞれパラメータ名
• 以下の 7 と 5 がそれぞれの値
• サーバーは,これらパラメータの値に基づいて,
サーバー側で計算(含む検索等)を行い,その結果
を新しいページとして返すのが普通.
11
復習
JSP and Servlet
• 共通点
• どちらもサーバーで実行される. • すなわち,クライアントに届いた時にはただのHTML • コレがJavaScriptとの大きな違い• JSP
• HTMLにJavaっぽいものを埋め込む. • 雰囲気はJavaScriptに似てるが,上記のようにサーバー内で実行される. • phpはコレに考え方が似ている. • オリジナルのクラス等を作成する場合は,Servletとの連携が必要.• Servlet
• Javaそのもの. • mainメソッドは書かないのが普通. • そもそも スーパークラスがフレームワーク的にできている. • Javaのprint機能でHTMLの行を表示しないと,クライアント側で解釈不能 になる. • どちらかといえば,JSPのサブルーチン的に使われるのが普通.12
サンプル
13
<HTML> <HEAD> <TITLE> JSP loop </TITLE> </HEAD> <BODY> <ul> <% int i;for(i=0; i<10; i++){ %>
<li> number <%= i*3 %> <% } %> </ul> </BODY> </HTML> // Simple Servlet import java.io.*; import javax.servlet.*; import javax.servlet.http.*;
public class Another extends HttpServlet { public void doGet(
HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
response.setContentType("text/html"); PrintWriter out = response.getWriter(); out.println("<html>"); out.println("<head>"); out.println("<title>Another!</title>"); out.println("</head>"); out.println("<body>"); out.println("<h1>Another!</h1>"); out.println("</body>"); out.println("</html>"); } }
動的なページ生成
• JSP/Servlet等のサーバーサイド処理は,「動的なペー
ジ生成」と呼ばれることがある.
• これは,サーバーおいてあるファイルを単に閲覧する
だけの単純なウエブページに比べ,プログラムで処理
して,ページを原則毎回生成しているからである.
• たしかに上記の通りだが,クライアントに届いた時点で
は,単なるHTMLになっている.
• よって,JavaScript等を含むクライアント到着後にも動
的にページが変化するものに比べれば,静的といえる.
14
JSPの基礎
• HTML等にJavaを記述する.
• <% と %> でJavaをはさむ.
• 単なるウエブサーバーはJSP(Java入りHTML)を解
釈できないので,別途,Webコンテナと呼ばれるプ
ログラムを準備する.
• tomcat6 はWebコンテナの一種.
• 内部的には埋め込まれたJava記述をJavaコンパイ
ラがコンパイルして,ページを動的に生成している.
15
セットアップしてほしい構成
• いわゆる,LAMP + Java/Servlet
16
Lenovo : クライアント Firefox等 : ウエブブラウザ CentOS 6.5 : サーバー apache 2.2 : ウエブサーバー PHP 5.3 : モジュール Tomcat6 : アプリケーションサーバー MySQL 5.1 : データベース HTTP JVM : モジュール復習
コレが WebコンテナJSPページの配置の仕方
• 次回のセットアップに従い,少なくとも,httpdとtomcat6を起
動されてることを確認.(詳細は次頁)
• 以下を実行し,適当なフォルダを作成
# cd /var/lib/tomcat6/webapps
# mkdir jindai
• 注 # はrootでの実行です.
• フォルダ名(上記ではjindai)はなんでもいいが英字にすること.
• JSPのファイルを作成して(後述)上記のフォルダに入れる.
仮に hiratuka.jsp とする.
• 適当なブラウザで以下のURLを見れば,JSPが動く.
http://192.168.0.6/tomcat/jindai/hiratuka.jsp
• 注 192.168.0.6 は各自実際のアドレスに置き換えてください.
• できれば友達等の他のマシンから見てもらうのがよい.
17
httpd, tomcat6の起動確認
• 以下のコマンドで確認できる.
• running と出ないと動いてないので,どっか問題が
ある.
JSPのページ作成
• ファイル名は英数字,拡張子は .jsp にする.
• 作成はLinux側でemacsやviで行うしかない.
• 仮想マシンの人はWinで作成して転送してもよい.
• 作成したファイルはhttpdやtomcatが読めるように
以下の設定を行う.
# chmod a+r hiratuka.jsp
• ファイルの中身は基本htmlだが,JSPとしての記述
は後述.
• Java部分は <% %> で囲うのが基本.
JSPページの要素
• 以下のような要素をHTMLファイルに埋め込める.
• ノリは<script>に似てる.
20
名前
構文
概要
Directive <%@ なんか %> ページ単位の処理法指定.charset等. 宣言 <%! なんか %> 変数,定数,メソッド宣言 Scriptlet <% なんか %> 実行される処理 Expression 式 <%= なんか %> =以降の式の値に置き換えられる Action Tag <jsp:なんか> 定型的な処理をタグ形式で記述 コメント <%-- なんか --%> コメント文,HTML式のコメント文<!- ->は 使わないこと.暗黙オブジェクト
• 以下のようなオブジェクト(インスタンス)が宣言なしで使える.
• 主にウエブとの情報共有に用いられる.
• 宣言部 (<%! %>)では使えないことを注意.
21
オブジェクト名 概要 application コンテナに関する情報等 config 設定ファイルへのアクセス exception ページ内で発生した例外情報を管理 out クライアントにデータを出力する手段.out.printlnはよくつかう. page JSPページそのもの. pageContext ページ単位で利用可能な情報. request httpリクエストへのアクセスを提供 response httpレスポンスを修正する場合に利用 session セッションの情報,次回以降.サンプルによる記述の実際
• scriptlet.jsp よくある例.Javaをhtmlの中にかけます.
• dclvar.jsp 変数を宣言して使います.
• dclmethod.jsp メソッドも宣言できます.
23
<%@ page contentType="text/html; charset=UTF-8" %> <%-- 標準ライブラリを使う場合,以下のようにする必要があり 自作のライブラリや3rd partyのライブラリを使う場合はServletのところで解説 --%> <%@ page import="java.util.ArrayList" %> <%@ page import="java.util.HashSet" %> <!DOCTYPE html> <html> <head><meta charset="utf-8"><title>scriptlet.jsp</title></head><body> <ol> <%
ArrayList<String> a=new ArrayList<String>(); // リストです HashSet<String> s=new HashSet<String>(); // 集合です
a.add("tako"); // なんとなく海産物が思いつく
a.add(“ika”); a.add(“awabi”); a.add("ikura"); a.add("tako"); // 重複してます a.add("uni"); a.add("ika"); // 重複してます // sは集合だから重複分は追加されない for(String i: a){s.add(i);} /* 実際みてみると,ちゃんと重複はカウントされてない */ for(String i: s){ out.println(“<li>”+i); } %> <ol></body></html>
非標準クラスの利用 (JSP)
• 通常のJava同様に java.lang 以外のクラスを利用する
には, import をする必要がある.
• 以下が標準的な書式である.
• JSP では java.lang 以外でも,以下がimportなしで利用
できる.
• javax.servlet.*, javax.servlet.jsp.*, javax.servlet.http.*
24
<%@ page contentType="text/html; charset=UTF-8" %>
<%-- java.lang以外のライブラリを使う場合,以下のようにする必要があり 自作のライブラリや3rd partyのライブラリも同様 --%> <%@ page import="java.util.ArrayList" %> <%@ page import="java.util.HashSet" %> <!DOCTYPE html> <html> <head> 以下,略
宣言部での変数
• <%! %>の宣言部で宣言された変数はtomcatが動
作している限り,存在し続けるらしい.
• よって,原理的には異なるページ間の情報共有に
もつかえそうだ.
• しかし,この変数は並列処理に対して安全ではな
い(Thread safe ではない)ので,そのような使い方
はお勧めしない.
• 一連の処理における情報共有では,後述の
session, 一般的な情報共有には後日話すデータ
ベースを利用すべき.
25
HTTPの詳細
• Hyper Text Transfer Protocol
• 基本的に以下のやりとりの対となる
• クライアント(ブラウザ)側から
「リクエスト」
を送る
• サーバー側から
「レスポンス」
がくる
• レスポンス,リクエストともに内容はテキストファイルで
ある.
• よって,直接,人間が目視で読むことが可能.
• HTTPレベルでは,リクエストに対するレスポンスが対
応付いているだけである.
• 同じブラウザからの連続したリクエストである等の一連
の処理(セッション)の識別はプログラムによって,プロ
グラマが管理しないといけない.
26
復習
もっとも基本的な例
• ブラウザが見たいページをリクエストして,
• そのページのデータがレスポンスとして返ってくる.
27
レスポンス:
ページの内容
リクエスト:
あるページを指定
http://www.a.com/index.html
ブラウザ復習
リクエストの種類
• 以下の5つがあるが,最初の2つがよく使われる.
• GET
• サーバー側にある情報をクライアントが取得(get)する
• POST
• サーバー側にクライアントが情報を送る(post)
• HEAD
• PUT
• DELETE
28
復習
リクエストの構造
• 以下の3つのパートからなる.
• リクエスト ライン
• どんなリクエストを送るかを示した部分.
• メッセージ ヘッダ
• メッセージ送り元であるクライアントの特性等のデータ群.
• Hostのデータは必須.
• 表示可能な言語,ブラウザの種類,受信可能なデータの種
類等を含む.
• メッセージ ボディ
• 送るメッセージの内容,必ず空行が一行いる.
• GETの場合は空行一行のみ.
• ヘッダとボディの間には空行がある.
29
復習
リクエストの例
30
GET / HTTP/1.1
Host: www.ana.co.jp
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:32.0) Gecko/20100101 Firefox/32.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: ja,en-us;q=0.7,en;q=0.3 Accept-Encoding: gzip, deflate
Cookie: ながいので略 Connection: keep-alive GET / HTTP/1.1
Host: www.kanagawa-u.ac.jp
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:32.0) Gecko/20100101 Firefox/32.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: ja,en-us;q=0.7,en;q=0.3 Accept-Encoding: gzip, deflate
Referer: http://www0.info.kanagawa-u.ac.jp/~kaiya/ Cookie: 長いので略 Connection: keep-alive Cache-Control: max-age=0
全日空のサイト
神大のサイト
復習
ブラウザ上の表示との対応
31
GET / HTTP/1.1 Host: www.kanagawa-u.ac.jp User-Agent: 略 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: ja,en-us;q=0.7,en;q=0.3Accept-Encoding: gzip, deflate
Referer: http://www0.info.kanagawa-u.ac.jp/~kaiya/ Cookie: 長いので略
Connection: keep-alive
リクエストライン等の構造
32
GET
/~kaiya/wa/
HTTP/1.1
Host:
www0.info.kanagawa-u.ac.jp
GET
/webstation/index.html
HTTP/1.1
Host:
www.kanagawa-u.ac.jp
復習
レスポンスの構造
• 以下の3つのパートからなる
• ステータス ライン
• リクエストが成功したか否かの情報.
• メッセージ ヘッダー
• サーバー側の情報等
• メッセージ ボディ
• レスポンスの中身.GETの場合,HTMLのページデー
タが入る.
• HTMLだけでなく,プログラムも封入される場合がある.
• ボディとヘッダーの間には空行があり.
33
復習
レスポンスの例
34
HTTP/1.1 200 OK
Date: Mon, 15 Sep 2014 12:00:06 GMT Server: Apache/2.2.15 (Scientific Linux)
Last-Modified: Thu, 28 Aug 2014 23:46:13 GMT Etag: "a1b81-686d-501b924552e21" Accept-Ranges: bytes Content-Length: 26733 Connection: close Content-Type: text/html <!DOCTYPE html> <html> <head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> 以下,長いので略
神大のサイト
レスポンスの結果の種類
• 200 リクエストが成功した
• 304 ページは更新されてない
• 400 リクエストが不正
• 403 アクセスが禁止されている
• 404 そんなページは無い
35
復習
サーバーにデータを送付する
• POST等に代表されるリクエストとともにサーバー
にデータを送付する方法については,中盤以降に
解説します.
• とりあえずは,GETに代表されるページデータを取
得する仕組みを理解しておいてください.
• なお,ブラウザでなくても,TCPを理解するプログラ
ムであれば,直接,リクエストをウエブサーバーに
送り,ページデータを取得することができる.
• たとえば,telnet コマンド等.
• wgetコマンドも,そのように作られている.
36
復習
JSPからのrequest/responseへのアクセス
• request, response ともに暗黙オブジェクトとしてアク
セスできる.
• それぞれに型は以下の通り
• javax.servlet.http.HttpServletRequest request
• javax.servlet.http.HttpServletResponse response
• 上記インタフェースで実装が要請されるメソッドは
実装されている.
• それぞれ詳細はAPIマニュアルを見ること.
37
form等から入力と request
• request から parameter のとりだし
• サンプル参照 getparm.html getparm.jsp
• formがあるページにて
• input タグ等を通して,ユーザー入力を key-value で取
得.
• action 属性で受け取り側のJSPページを指定
• JSPページにて
• 暗黙オブジェクト request に getParameter メソッドを使っ
て,key-value の value を String として得る.
• valueが配列の場合,getParameterValues()メソッドを利
用.
responseの設定
• クライアントに返す情報が設定できる.
• 例えば,ページの encoding: UFT-8 や US-ASCII
等.
• クッキーの設定にも使える.(次回)
html以外の生成
• JSPに限らず,response の結果として,テキストファ
イルやPDF等も生成できる.
• その際,contentTypeを指定する必要がある.
• サンプル barchart.jsp 単なるテキストファイル
40
<%@ page contentType="text/plain; charset=UTF-8" %> <%
for(int i=0; i<20; i++){
out.print(String.format("%02d ", i)); for(int j=0; j<i; j++){ out.print("*"); } out.println(); } %>