Powered by SmartDoc

HTTPプロトコル

HTTPプロトコル

みなさんがあるWebページを見ようとするとき、Webブラウザを使ってそのページのURLを入力するか、あるいはリンクをクリックします。Webブラウザは、あなたが見たいページを置いているWebサーバに接続します。WebブラウザとWebサーバは、HTTPというプロトコルに従って通信します。

ホスト名・ポート番号・URL

インターネットでは、TCP/IPというプロトコルに従い、IPアドレスとポート番号を使って通信します。TCP/IPを用いているHTTPによる通信でも、当然ながらIPアドレスとポート番号が必要です。

一般にURLは、次のような構造になっています。

http://ホスト名:ポート番号/パス?クエリー

まず、WebサーバのIPアドレスまたはホスト名が必要です。IPアドレスはDNSによってホスト名に変換されるので、どちらでも使えます。ポート番号の記述は、80番であるとき省略できます。パスは、Webサーバ上のファイルのありかを示しています。クエリーについては、後で説明します。

URLは、URIと記述されることもあります。URIは、特定の情報のありかを指定するための記法で、URLもURIに含まれます。

例1)
http://www.wakhok.ac.jp/index.html

www.wakhok.ac.jpというホストに接続します。また、このURLではポート番号が省略されているので、80番のポートを使うことになります。

例2)
http://localhost:8080/

この例では、8080番のポートを使って、localhost (ブラウザが動いているコンピュータ)に接続します。

HTTPプロトコルの通信手順

HTTP (HyperText Transfer Protocol)は、WebブラウザとWebサーバが通信するためのプロトコルです。HTTPの最新バージョンはHTTP/1.1であり、RFC 2616によって定められています。

Webブラウザからhttp://localhost:8080/examples/jsp/index.htmlというURLにアクセスするとき、WebブラウザとWebサーバは次のように働きます(図3.1[HTTPプロトコル]参照)。

HTTPプロトコル
  1. Webブラウザは、URLを解析して、URL中のホストとポートに接続する。この場合、ホストlocalhostのポート8080番に接続する。
  2. WebブラウザとWebサーバとの接続が確立されると、Webブラウザは、Webサーバに対して要求(request)を出す。この場合、「/examples/jsp/index.htmlを取得する」という要求となる。
  3. Webサーバは、Webブラウザからの要求を処理して、応答(response)を返す。この場合、index.htmlの内容と、いくつかの関連する情報を応答とする。
  4. Webブラウザは、応答の内容を表示する。この場合、index.htmlの内容を表示する。

Webブラウザからの要求 (request)

要求の形式

Webブラウザは、Webサーバとの接続が確立されると、次のように要求を出します。

GET /examples/jsp/index.html HTTP/1.1
Host: localhost
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; ja-JP; rv:0.9.2) \
    Gecko/20010726 Netscape6/6.1
Accept: text/xml, application/xml, application/xhtml+xml, text/html;q=0.9, \
    image/png, image/jpeg, image/gif;q=0.2, text/plain;q=0.8, text/css, \
    */*;q=0.1
Accept-Language: ja
Accept-Encoding: gzip,deflate,compress,identity
Accept-Charset: Shift_JIS, utf-8;q=0.66, *;q=0.66
Keep-Alive: 300
Connection: keep-alive

一般的に、要求は次のような形式になります。

リクエスト行
ヘッダ
空行
本文

本文は無いこともあります。この例でも、本文はありません。本文が必要な例は、後で説明します。

リクエスト行とメソッド

要求の最初の一行は、このようになっています。これがリクエスト行です。

GET /examples/jsp/index.html HTTP/1.1

リクエスト行は、次のような形式になります。

メソッド   URI   HTTPのバージョン

最初の「メソッド」では、どのような要求を出すか指定します。ここでは、指定したURIの内容を取得する"GET"というメソッドが使われています。HTTP1.1では次のようなメソッドが利用できます。

GET
URIの内容を取得する
POST
URIに情報を送信する
HEAD
URIについてのヘッダ部分のみを取得する
PUT
URIの内容を作成・置換する
DELETE
URIの内容を削除する
OPTIONS
URIに対して利用できるメソッドの一覧を取得する
CONNECT
今後「プロキシ」と呼ばれるもので使われる予定
TRACE
クライアントからの要求をそのまま返す

URIは、そのサーバの"/ (ルート)"からの場所を指定するのが普通です。

最後に、HTTPのバージョンを指定します。ここでは、HTTP1.1とします。

このリクエスト行の働きをまとめると、「HTTP1.1で/examples/jsp/index.htmlの内容を取得する」ということになります。

ヘッダ

ヘッダの形式は次の通りです。複数のヘッダをつけることができます。

フィールド名: 値

最初に示すのは、どの名前のホストにアクセスするのか指定するヘッダです。HTTP1.1では必須となります。

Host: localhost

他にもいくつかのヘッダがあります。次に示すUser-Agentというヘッダは、WebサーバにアクセスしているWebブラウザの名称を示します。この例では、Windows上のNetscape6を使っていることがわかります。

User-Agent: User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; ja-JP; \
    rv:0.9.2) Gecko/20010726 Netscape6/6.1

Webサーバからの応答 (response)

応答の形式

Webサーバは、Webブラウザからの要求を受け取ると、次のような応答を返します。

HTTP/1.1 200 OK
ETag: W/"7487-1032772982000"
Last-Modified: Mon, 23 Sep 2002 09:23:02 GMT
Content-Type: text/html
Content-Length: 7487
Date: Tue, 29 Apr 2003 07:26:13 GMT
Server: Apache Coyote/1.0

<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="GENERATOR" content="Mozilla/4.61 [en] (WinNT; I) [Netscape]">
   <meta name="Author" content="Anil K. Vijendran">
   <title>JSP Examples</title>
<!--
  Copyright (c) 1999 The Apache Software Foundation.  All rights 
  reserved.
-->
</head>

<body bgcolor="#FFFFFF">
<p>These examples will only work when these pages are being served by a

(中略)

</body>
</html>

応答の形式は、次の通りです。要求の形式とほとんど同じです。

ステータス行
ヘッダ
空行
本文

本文は、HTMLで書かれたWebページの内容になっています。

ステータス行

応答の最初の一行は、このようになっています。これがステータス行です。

HTTP/1.1 200 OK

ステータス行は、次のような形式になります。

HTTPのバージョン   ステータスコード   説明文

最初にHTTPのバージョンが出てきます。この場合では、HTTP1.1となります。

次に、「ステータスコード」と「説明文」が出てきます。ステータスコードは3桁の数字で、サーバからの応答がどのような種類のものであるかを示します。「説明文」は、そのステータスコードについての説明です。

表3.1[ステータスコードの分類]にステータスコードの分類を示します。また、表3.2[代表的なステータスコード]に代表的なステータスコードを示します。

ステータスコードの分類
200番台 要求が正常に処理された
400番台 クライアント側に問題がある
500番台 サーバ側に問題がある
代表的なステータスコード
ステータスコード 説明文 概要
200 OK 成功
403 Forbidden URIに対するアクセスを拒否
404 Not Found URIに該当するものがない
500 Internal Server Error リクエストの実行中にエラーが起きた

Webブラウザを使っていると、既に無くなっているページにアクセスして「404 Not Found」というメッセージを目にすることがあると思います。この「404」という数字がステータスコードです。

ヘッダ

応答の2行目からは、ヘッダとなります。

ETag: W/"7487-1032772982000"
Last-Modified: Mon, 23 Sep 2002 09:23:02 GMT
Content-Type: text/html
Content-Length: 7487
Date: Tue, 29 Apr 2003 07:26:13 GMT
Server: Apache Coyote/1.0

応答のヘッダの形式も、要求のヘッダの形式と同じく、次のようになっています。

フィールド名: 値

それでは、1行ずつ見てみましょう。

ETag: W/"7487-1032772982000"

本文の内容を識別するためのIDのような役割を果たします。

Last-Modified: Mon, 23 Sep 2002 09:23:02 GMT

本文に書かれているWebページが最後に更新された日時を表示しています。

Content-Type: text/html

本文に書かれているものがどういった種類のものかを示しています。どんな種類があるかは、電子メールなどで用いられているMIMEという規格で定められています。代表的なMIME型を表3.3[代表的なMIME型]に示します。

代表的なMIME型
text/html HTML文書
text/xml XML文書
text/plain テキスト
image/gif GIF画像
image/jpeg JPEG画像
video/mpeg 動画(MPEG)

この場合は、HTMLが指定されています。

Content-Length: 7487

本文のサイズを表示しています。

Date: Tue, 29 Apr 2003 07:26:13 GMT

応答を返した日時を表示しています。

Server: Apache Coyote/1.0

サーバとして使っているソフトウェア名を表示しています。"Apache Coyote"は、Tomcatを単独でWebサーバとして使う場合のプログラムの名前です。

Webブラウザの働き

これまで見てきたように、HTTPは要求と応答がペアになっています。1回の要求につき、1つのファイルしか取得できません。

しかし、Webページには、1つのHTMLファイルだけでなく、複数の画像ファイルが含まれていることがあります。また、フレームを使ったWebページには、複数のHTMLファイルが含まれています。

Webブラウザは最初に取得したHTMLを解析し、もし<img>タグを見つけたら、その画像ファイルを取得する要求を出します。このようにしてリクエストを繰り返し、1つのWebページを完成させます。

フォームからの入力とPOST・GETメソッド

HTMLのフォーム

サーチエンジンや掲示板のサイトでは、ユーザからの入力に応じてWebページが変化していきます。こうしたサイトでは、HTMLのフォームを使ってユーザからの入力を受け取ります。

フォームで姓名を入力してもらい、そのデータをそのまま出力する例を紹介します。

最初に、このフォームのHTMLです。

doGet.html
<?xml version="1.0" encoding="Shift_JIS" ?>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type"
      content="text/html; charset=Shift_JIS" />
<title>フォームのテスト</title>
</head>
<body>

<p>姓名を入力してください:</p>
<form method="get" action="name.jsp">
<p>姓: <input type="text" name="familyName" /></p>
<p>名: <input type="text" name="givenName" /></p>
<p>
&lt;input type="submit" value="実行" /&gt;
&lt;input type="reset" value="キャンセル" /&gt;
</p>
</form>

</body>
</html>

このフォームは、図3.2[姓名を入力するフォーム]のような画面になります。

姓名を入力するフォーム

「姓」のところに入力された文字は、inputタグのname属性の値であるfamilyNameというパラメータに格納されます。同様に、「名」のところに入力された文字は、givenNameというパラメータに格納されます。

フォームから入力されたデータは、HTTPのPOSTメソッドかGETメソッドを使って、そのデータを処理するプログラムに渡されます。

POST の利用

POSTメソッドを使ってデータを送信するときには、HTMLでformタグのmethod属性に"post"という文字を指定します。

<form method="post" action="name.jsp">
  .....
  .....
</form>

POSTメソッドを利用する場合にどのような要求になるか見てみましょう。

POST /test/name.jsp HTTP/1.1
Host: localhost
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; ja-JP; rv:0.9.2) \
    Gecko/20010726 Netscape6/6.1
Accept: text/xml, application/xml, application/xhtml+xml, text/html;q=0.9, \
    image/png, image/jpeg, image/gif;q=0.2, text/plain;q=0.8, text/css, \
    */*;q=0.1
Accept-Language: ja
Accept-Encoding: gzip,deflate,compress,identity
Accept-Charset: Shift_JIS, utf-8;q=0.66, *;q=0.66
Keep-Alive: 300
Connection: keep-alive
Cookie: JSESSIONID=6EDECB114441C404C531913C0C8D6DA9
Referer: http://localhost:8081/test/doPost.html
Content-type: application/x-www-form-urlencoded
Content-Length: 35

familyName=maruyama&givenName=fujio

GETメソッドのときと違い、本文があります。次のようになっています。

familyName=maruyama&givenName=fujio

この文字列を「クエリー」と呼びます。このクエリーを大きく分けると

familyName = maruyama
&
givenName  = fujio

のようになります。familyNameパラメータの値が"maruyama"で、givenNameパラメータの値が"fujio"になっており、この2つのパラメータを"&"でつなげています。

このようにPOSTメソッドでは、クエリーを要求の本文にすることでデータを送信しています。

POSTメソッドによる要求を処理したプログラムは図3.3[実行結果 (POST)]のような結果を表示します。

実行結果 (POST)

GET の利用

GETメソッドを使ってデータを送信するときには、HTMLでformタグのmethod属性に"get"という文字を指定します。

<form method="get" action="name.jsp">
  .....
  .....
</form>

GETメソッドを利用する場合にどのような要求になるか見てみましょう。

GET /test/name.jsp?familyName=maruyama&givenName=fujio HTTP/1.1
Host: localhost
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; ja-JP; rv:0.9.2) \
    Gecko/20010726 Netscape6/6.1
Accept: text/xml, application/xml, application/xhtml+xml, text/html;q=0.9, \
    image/png, image/jpeg, image/gif;q=0.2, text/plain;q=0.8, text/css, \
    */*;q=0.1
Accept-Language: ja
Accept-Encoding: gzip,deflate,compress,identity
Accept-Charset: Shift_JIS, utf-8;q=0.66, *;q=0.66
Keep-Alive: 300
Connection: keep-alive
Cookie: JSESSIONID=8535F377D0773414C253F3B597BB4977
Referer: http://localhost:8081/test/doGet.html
If-Modified-Since: Sun, 19 Jan 2003 00:39:50 GMT

POSTメソッドと違って本文は無く、リクエスト行にパラメータが含まれています。

GET /test/name.jsp?familyName=maruyama&givenName=fujio HTTP/1.1

この部分を分解すると

GET
/test/name.jsp
?
familyName=maruyama&givenName=fujio
HTTP/1.1

JSPのファイル名に続けて"?"を置き、その後ろにPOSTメソッドと同じようにクエリーが続きます。つまり、URI中にパラメータが書かれます。

GETメソッドによる要求を処理したプログラムは図3.4[実行結果 (GET)]のような結果を表示します。

実行結果 (GET)

このようにGETメソッドでは、URI中にクエリーを含めることでデータを送信しています。

GET と POST の使い分け

GETとPOSTでは、クエリーの送信方法に違いがあります。

多くの場合、POSTメソッドを利用するのが良いとされています。GETメソッドでは送信できるクエリーのサイズに上限があるからです。また、ユーザ名とパスワードを入力させるような場合、GETメソッドではURI中にパスワードが表示されてしまうので、POSTメソッドを利用するのが良いでしょう。さらに、GETメソッドでは入力されたデータに含まれる改行を渡せません。掲示板のような目的には使えないでしょう。POSTメソッドにはそのような制限はありません。

しかし、GETメソッドを利用するのが良い場合もあります。例えば、Googleや商品データベースなどの検索結果をブックマークに登録したり、リンクを貼ることが予想される場合には、GETメソッドを使わなければなりません。GETメソッドではクエリーがURIに含まれるので後から参照できます。しかし、POSTメソッドだと本文中にクエリーを含めなければならないので、後から参照できなくなります。

JSPでの要求・応答の処理

request 変数と response 変数

JSPでは、Webブラウザからの要求を処理するためにrequestという変数を使います。また、Webサーバからの応答を処理するためにresponseという変数を使います。

まずはrequest変数の使い方を示しましょう。request変数のメソッドを利用することで、リクエスト行とヘッダの内容の一部を表示させています。

<%@ page contentType="text/html; charset=Shift_JIS" %>

<html>
<head>
<title>要求の処理</title>
</head>
<body>

<% request.setCharacterEncoding("Shift_JIS"); %>

<ul>
<li>Method: <%= request.getMethod() %> </li>
<li>Request URI: <%= request.getRequestURI() %> </li>
<li>Protocol: <%= request.getProtocol() %> </li>
<li>Remote Address: <%= request.getRemoteAddr() %> </li>
</ul>

</body>
</html>

getMethod()というメソッドでは、要求で利用したメソッド名を表示しています。

request.getMethod()

getRequestURI()は、リクエスト行で指定されたURIを返します。

request.getRequestURI()

getProtocol()は、リクエスト行で指定されたHTTPのバージョンを返します。

request.getProtocol()

getRemoteAddr()は、要求を送ったブラウザのIPアドレスを返します。

request.getRemoteAddr()

このJSPページの出力例を示します。

    * Method: GET
    * Request URI: /test/name.jsp
    * Protocol: HTTP/1.1
    * Remote Address: 127.0.0.1

もう一つの変数であるresponseは、主としてJSPページから他のページに処理をまかせるときに利用します。

クエリーの処理

JSPでは、GETの場合でもPOSTの場合でもrequest変数を使ってクエリー中のパラメータの値を取得できます。

<%@ page contentType="text/html; charset=Shift_JIS" %>

<html>
<head>
<title>入力された名前について</title>
</head>
<body>

<% request.setCharacterEncoding("Shift_JIS"); %>

<p>
姓:
<%= request.getParameter("familyName") %>
</p>

<p>
名:
<%= request.getParameter("givenName") %>
</p>

</body>
</html>

request.getParameter()というメソッドを使って、パラメータの値を出力しています。次の部分では、familyNameパラメータの値を出力しています。

request.getParameter("familyName")