狠狠撸

狠狠撸Share a Scribd company logo
基礎セミナー初級者シリーズ 
贬罢罢笔とサーブレット 
日本Javaユーザグループ/株式会社アットウェア 
牧野隆志
目的 
? サーブレットが動作する仕組み 
を学びます 
– 深く詳細までは取り上げません 
– APIドキュメントを読んだり、書籍、Webサイトな 
どを参照してください 
– ミドルウェアやWebアプリケーションフレーム 
ワークが何をやっているかなんとなく想像がつ 
くようになるとうれしいです
こういうのを作ります 
JJUG 
任意の文字列を入力す 
るとGoogleみたいに検索 
結果が一覧表示される
これがサーブレットでできてます 
? Webブラウザから入力した文字列(検索 
キーワード)を解釈して、検索して、結果を 
一覧で表示しています 
– あのGoogleだって、基本的にやってることは同じ(はず) 
Webブラウザ 
①入力文字列 
⑤表示 
サーブレット 
②入力文字列解釈 
③検索 
④結果表示画面作成
サーブレット(Servlet)とは 
? JavaでWebアプリケーションを構築するた 
めの仕組み 
? 余談ですが、WebアプリケーションはJavaでなくて 
も作れます 
? J2EE/JavaEEの一機能として仕様が決 
まっていて、仕様に従ってコードを書けば 
動的なWebサイトを立ち上げることができ 
ます 
むずかしい話はとりあえずおいておきましょう
まずはWebブラウザに表示 
? Webブラウザは、HTMLで記述された内容 
を画面に表示する 
<html> 
<head> 
<title>検索</title> 
<meta http-equiv="Content-Type" 
content="text/html; charset=UTF-8"> 
</head> 
<body> 
<h2>Googleみたいな検索</h2> 
<form method="GET" action="search"> 
<input type="text" name="query"> 
<input type="submit" value="検索" > 
</form> 
</body> 
</html>
public class SearchServlet extends HttpServlet { 
protected void doGet(HttpServletRequest request, 
HttpServletResponse response) 
throws ServletException, IOException { 
: 
} 
protected void doPost(HttpServletRequest request, 
HttpServletResponse response) 
throws ServletException, IOException { 
: 
} 
} 
サーブレットを見てみましょう
サーブレットのクラス 
import javax.servlet.http.*; 
public class SearchServlet 
extends HttpServlet { 
javax.servlet.http.HttpServlet 
のサブクラスにします 
クラス名は何でも構いません
javax.servlet.http.HttpServlet 
? JavaEEで規定された抽象(abstract)クラス 
? Webアプリケーションとしてブラウザからの 
要求に対して行う処理をHttpServletを継 
承したクラスに書きます 
? 処理に応じて、HttpServletのメソッドをオー 
バーライドします
サーブレットで特に重要なメソッド 
? doGet 
HTMLのform action=”GET”に対してsubmitボ 
タンが押された場合に呼び出されるメソッド 
? doPost 
HTMLのform action=”POST”に対してsubmit 
ボタンが押された場合に呼び出されるメソッド 
それぞれのactionに対する処 
理をメソッドの中に記述する
doGetメソッド 
protected void doGet(HttpServletRequest req, 
HttpServletResponse resp) 
throws ServletException, 
IOException 
パラメータ: 
req - Webブラウザからの要求 
resp - Webブラウザへの応答
doPostメソッド 
? doGetとパラメータ、戻り値、例外が一緒 
GETとPOSTで処理の内容が違うことはほとんどないの 
で、doGetとdoPostのいずれからも別のメソッドを単に呼 
び出すだけにすることが多い 
protected void processRequest(???) { 
// ここに実際の処理を書く 
} 
protected void doGet(???) { 
processRequest(req, resp); 
} 
protected void doPost(???) { 
processRequest(req, resp); 
}
Webブラウザからの要求の内容 
? Webブラウザで入力した文字列がdoGet 
(あるいはdoPost)メソッドの一つ目のパラ 
メータHttpServletRequestオブジェクトに 
セットされます 
より正確には、HTMLのsubmitボタンを押されたform 
に含まれるinput要素の内容(テキストボックスに入力 
した文字列やチェックしたラジオボタンの名称など)が 
セットされます
HttpServletRequestのパラメータ 
<input type="text" name="query"> 
JJUG 検索 
HttpServletRequest 
“query” 
protected void doGet(HttpServletRequest req,… 
String query = req.getParameter("query"); 
=>“JJUG” 
JJUG
サーブレットの主になる処理 
? HttpServletRequestの内容に応じて、サー 
ブレット毎に必要な処理を行います 
今回の例だとGoogleみたいな検索処理 
String result[] = search(query); 
? サーブレットとは別のクラスに処理を委譲したほ 
うがよい 
– ビジネスロジックがサーブレット(HttpServlet)に依存 
するのは汎用性が無くなるため(他で使えない) 
– 一般的なWebアプリケーションフレームワークの役割
表示したい内容をHTMLにします 
? 処理が終わったら、結果をWebブラウザで 
表示できるように加工します 
→HTML文書を生成します 
最初に「Webブラウザは、HTMLで記述された内容 
を画面に表示する」とあるとおり 
? doGet(あるいはdoPost)メソッドの二つ目 
のパラメータHttpServletResponseオブジェ 
クトからgetWriterにてWriterオブジェクトを 
取り出し、HTML文書を書き込みます
HTMLを生成するのは面倒だけど 
// まず結果がHTMLであることを明確にして 
resp.setContentType("text/html;charset=UTF-8"); 
// Writerを取り出して 
PrintWriter out = resp.getWriter(); 
// ひたすらHTMLを書き込んでいく… 
out.println("<html>"); 
out.println("<head>"); 
: 
: 
out.println("</body>"); 
out.println("</html>"); 
out.close(); 
Javaソースコード中に 
HTMLを書くわずらわし 
さを解消するJSPという 
技術がありますが、ここ 
では紹介しません
こんな感じで表示 
<html> 
<head> 
<title>検索結果</title> 
</head> 
<body> 
<h2>JJUGの検索結果</h2> 
<ul> 
<li>JJUGについて 
<li>JJUGとは 
<li>JJUGの謎に迫る 
<li>What is JJUG 
</ul> 
</body> 
</html>
ひととおりの動作を見ました 
? Webブラウザでsubmitボタンを押すとサー 
ブレットのdoGetかdoPostが呼ばれる 
? formに入力したデータが 
HttpServletRequestにセットされている 
? サーブレットでHttpServletRequestの内容 
に基づき処理をして、結果をHTMLにして 
HttpServletResponseにセットする 
? Webブラウザに表示される
サーブレットが複数ある場合は? 
? formひとつでサーブレットがひとつだったけ 
ど、ページが複数あったり、formが複数 
あったらどうする? 
→ web.xmlにformのaction(パス)毎に呼 
び出すサーブレットを指定します
サーブレット 
のクラス名 
web.xml 
<?xml version="1.0" encoding="UTF-8"?> 
<web-app …省略…> 
<servlet> 
<servlet-name>SearchServlet</servlet-name> 
<servlet-class>jjug.SearchServlet</servlet-class> 
</servlet> 
<servlet-mapping> 
<servlet-name>SearchServlet</servlet-name> 
<url-pattern>/search</url-pattern> 
</servlet-mapping> 
</web-app> 
HTMLのform 
actionに設 
定したパス
Webブラウザから入力すると 
Webブラウザから入力すると、web.xmlの 
servlet-mappingに従って、サーブレットを 
呼び出す??? 
web.xmlを参照して、サーブレットを呼び出 
しているのは誰? 
Webブラウザ? 
ではありません
そもそもサーブレットを動かしてるのは 
? サーブレットコンテナ(Webコンテナ) 
– サーブレットを実行するためのミドルウェア 
– J2EE/JavaEEのサーブレットの仕様に基づき、 
サーブレットアプリケーションを実行します 
– 代表的なものはApache Tomcat 
– サーブレットに限らず、J2EE/JavaEEの全ての 
仕様を満たしたGlassFish、BEA WebLogic、 
IBM WebSphereなどのアプリケーションサーバ 
でもサーブレットは実行できます
Webブラウザから入力すると 
? Webブラウザから入力すると、ネットワーク 
を介してサーブレットコンテナに送信され、 
内容をHttpServletRequestにセットして 
サーブレットを起動する 
Webブラウザ 
サーブレットコンテナ 
サーブレット 
web.xml 
送信 
起動
サーブレットが結果をセットすると 
? サーブレットがHttpServletResponseにセッ 
トした内容をサーブレットコンテナがWebブ 
ラウザに返す 
Webブラウザ 
サーブレットコンテナ 
サーブレット 
返信
Webブラウザとサーブレットの通信 
Webブラウザ 
Webブラウザから入 
力された情報の通知 
サーブレット 
入力された情報を元に 
処理した結果の返信 
ネットワーク上で情報のやり 
取り(通信)が行われている
Webブラウザからサーブレットへ 
? こんな情報が通知されているはず 
– HTMLのformに書かれたaction(パス) 
– formのinputにWebブラウザで入力された文 
字列など
こんなのが送られてます 
GET /jjug_servlet/search?query=JJUG HTTP/1.1 
Host: localhost:8080 
User-Agent: Mozilla/5.0 (Macintosh; U; … 
Accept: text/xml,application/xml, … 
Accept-Language: ja,en-us;q=0.7,en;q=0.3 
Accept-Encoding: gzip,deflate 
Accept-Charset: Shift_JIS,utf-8;q=0.7,*;q=0.7 
Keep-Alive: 300 
Connection: keep-alive 
Referer: http://localhost:8080/jjug_servlet/… 
ちなみにWiresharkと 
いうソフトを使いました
これがHTTPです 
? なんかごちゃごちゃしてますが、ちゃんと決 
められた規則に従って送られています 
? この規則のことを“HTTP”といいます 
– Hypertext Transfer Protocol 
– HTMLやXMLなどのハイパーテキストをWebブ 
ラウザとWebサーバで送受信するためのプロト 
コル 
– 実際にはハイパーテキスト以外のコンテンツ、 
たとえば画像なども送受信できます 
? HTTPは単純な送信(リクエスト)と返信(レ 
スポンス)の組み合わせ
プロトコルとは 
? ネットワーク上で情報をやり取りするため 
の決まりごとを“プロトコル”といいます 
? コンピュータ?ソフトウェアは融通が利かな 
いので、厳格に決められたとおりに情報を 
やり取りしなければなりません
一行目に注目すると 
GET /jjug_servlet/search?query=JJUG 
?GET: GETメソッド 
?/jjug_servlet/search: actionで指定したパス 
?query=JJUG: inputタグのnameと入力した文字列
HTTP(リクエスト)の構成 
リクエストライン 
一行目GET /jjug_servlet/search?query 
リクエストヘッダ 
空行 
メッセージボディ 
Host: localhost:8080 
User-Agent: Mozilla/5.0 (Macin 
Accept: text/xml,application/x 
Accept-Language: ja,en-us;q=0. 
: 
POSTメソッドの場合、ここ 
にformの内容が並ぶ 
二行目 
~ 
改行まで 
改行から 
~ 
末尾まで
返信(レスポンス)の内容 
HTTP/1.x 200 OK 
X-Powered-By: Servlet/2.5 
Server: Sun Java System Application Server 9.1_01 
Content-Type: text/html;charset=UTF-8 
Content-Length: 204 
Date: Sun, 13 Apr 2008 16:17:10 GMT 
<html> 
<head> 
<title>検索結果</title> 
</head> 
<body> 
<h2>JJUGの検索結果</h2> 
:
HTTP(レスポンス)の構成 
ステータスライン 
一行目HTTP/1.x 200 OK 
レスポンスヘッ 
ダ 
空行 
メッセージボディ 
X-Powered-By: Servlet/2.5 
Server: Sun Java System Applic 
Content-Type: text/html;charse 
Content-Length: 204 
<html> 
<head> 
<title>検索結果</title> 
</head> 
<body> 
: 
: 
二行目 
~ 
改行まで 
改行から 
~ 
末尾まで
ステータスライン 
HTTP/1.x 200 OK 
?200:ステータスコード(成功) 
処理結果をコードで示します 
主なステータスコード 
200 OK. 成功 
403 Forbidden. 権限がないなど、アクセスが禁止されている 
404 Not Found. リソース(ファイル)が見つからない 
500 Internal Server Error. サーバー内部にエラーが発生した 
Service Unavailable. サービスが一時的に過負荷やメンテ 
ナンスで使用不可能である 
503
レスポンスヘッダ 
? Content-Type: text/html;charset=UTF-8 
– メッセージボディ(コンテンツ)の種類を示します 
– サーブレットで設定した内容 
resp.setContentType("text/html;charset=UTF-8"); 
? Content-Length: 204 
– メッセージボディ(コンテンツ)の長さを示します
レスポンスメッセージボディ 
? Webブラウザに表示するHTML 
– サーブレットでWriterに書き込んだ内容 
PrintWriter out = resp.getWriter(); 
out.println("<html>"); 
out.println("<head>"); 
: 
out.println("</html>"); 
out.close(); 
? HTMLでなくてもよい
ちなみにWebブラウザじゃなくても 
? HTTPは単純な文字列で構成されたプロト 
コルなので、Webブラウザじゃなくても簡単 
に扱えます 
? 例えば、UNIXやWindowsのtelnetコマンド 
でサーブレットコンテナに接続して、HTTP 
のリクエストを入力すれば結果が返ってき 
ます
telnetで接続してみた 
$ telnet 127.0.0.1 8080 
Trying 127.0.0.1... 
Connected to 127.0.0.1. 
Escape character is '^]'. 
GET /jjug_servlet/search?query=JJUG HTTP/1.0 
HTTP/1.1 200 OK 
X-Powered-By: Servlet/2.5 
Server: Sun Java System Application Server 9.1_01 
Content-Type: text/html;charset=UTF-8 
Content-Length: 204 
Date: Mon, 14 Apr 2008 05:08:41 GMT 
Connection: close 
<html> 
: 
: 
</html> 
入力 
入力 
Webブラウザじゃなくてもちゃ 
んと結果が返ってきます
サーブレットコンテナも作ってみよう 
? サーブレットコンテナはこんなことをやって 
るはず 
① Webブラウザがネットワークを介してリクエス 
トを送信してくるのを待ち受ける 
② HTTPリクエストの内容を解釈し、web.xmlに 
従い、呼び出すサーブレットを決定する 
③ パラメータをHttpServletRequestにセットする 
④ サーブレットを呼び出す 
⑤ HttpServletResponseにセットされた結果を 
Webブラウザに返す
そんなに難しくありませんね 
? ホントはサーブレットの仕様はもっともっと 
いっぱいあって、複雑です 
? でも、基本的には全てこの動作の延長に 
あります
最後に 
今日の話は明日からすぐ役に立つもので 
はありませんが、何か問題が起きた時に 
解決のヒントになったり、ミドルウェアやフ 
レームワークそのものに興味を持っていた 
だくきっかけになればうれしいです 
注)この解説の中には概要を理解していただくことを優先し、 
一部正確ではない記述もあります。ご了承ください。

More Related Content

贬罢罢笔とサーブレット