Fujitsu The Possibilities are Infinite

 

Java技術によるWebアプリケーション開発入門
1章:HTTPプロトコルとサーバへのリクエスト


Webアプリケーションの話は、まずHTTPから始めなくてはなりません。 WebアプリはHTTPを前提として作られているからです。 HTTPはTCPやIPと並んでインターネットを支える重要なプロトコル(通信規約)です。 ここではHTTPについて簡単に説明します(注1)

HTTP(HyperText Transfer Protocol)

HTTPはクライアントとサーバ間で行われる通信の規約を定めたものです。 HTTPではクライアントからサーバに送るデータをリクエスト、サーバからクライアントに送るデータをレスポンスと言います。

HTTPの最大の特徴はあるクライアントからのリクエストに対しサーバがそのクライアントへレスポンスを返すと、それで処理が完結することです。 つまり、サーバは各クライアントとの過去のやりとりを管理していません。 したがってサーバの負荷が軽く、1台のサーバで多くのクライアントに同時にサービスすることができます。 言い換えればクライアント当たりのサーバのコストが安いわけで、これがHTTPが成功した原因の1つとも言われています。

このように1回ごとに接続が完結し、過去の情報を管理しないやり方をステートレス(stateless)と言います。 これに対し、複数回のやりとりの間、相手のことを意識しているやり方をステートフル(stateful)と言います。

(注1) HTTPの仕様はRFC(Request for Comments)と呼ばれる文書でインターネット上に公開されています。 HTTP/1.1はRFC2616として規格化されています。 http://www.ietf.org/rfc/rfc2616.txt で参照できます。 ここは英語ですが、有志による日本語訳が http://www.studyinghttp.net/cgi-bin/rfc.cgi?2616 にあります。

リクエスト

リクエストはクライアントからサーバへの情報です。 リクエストはリクエスト行、ヘッダー部(メッセージヘッダー)、およびボディ部(メッセージボディ)からなっています。 リクエスト行にはリクエストの種類(メソッド名)を記述します。 ヘッダー部にはクライアントが扱える言語やデータの形式(イメージ情報が扱えるか否か)などの情報を、ボディ部にはサーバに送る情報を記述します。

主なリクエストとその役割は以下の通りです。

  • GETメソッド: クライアントがサーバの情報を取得する
  • POSTメソッド: クライアントからサーバに情報を送る
  • HEADメソッド: サーバ情報のヘッダー部分を取得する

リクエスト行にはリクエストの種類(メソッド名)の他に、対象となるソースのURL、およびHTTPの版数を記述します。 以下にGETメソッドのリクエスト行の例を示します。 このリクエストは対象ソース(jp.fujitsu.com/itj/)の取得要求を示しています。


図解: リクエスト

POSTメソッドのリクエスト行の形式はGETと同じです。 ただし、POSTメソッドにはボディ部があり、対象ソースにボディ部のデータを受け入れるように要求しています。 この要求に対してどの様なレスポンスが返るかは対象ソースの作りによります。

HEADメソッドは、サーバがレスポンスにおいてボディ部を返さない事を除けばGETと同一です。 したがってリクエスト行の形式もGETと同様になります。 HEADメソッドはサーバの情報を取得する前に、その最終更新日時を確認するためによく使われます。 クライアントが持っている情報の日時と同じであれば、わざわざ受け取る必要がないからです。

GETメソッド

GETメソッドは本来サーバからの情報(下り情報)を得るためのものですが、どんな情報が得たいかをサーバに伝えるための上り情報を付加することができます。 しかし、もともと上り情報の送信が目的ではないので、ボディ部ではなくリクエスト行のURLのうしろの ? で始まる文字列(クエリ文字列)に付けて送ります。 すなわち、GETメソッドはリクエスト行とヘッダー部だけで構成され、ボディ部はありません。 以下にクエリ文字列付きのGETメソッドの例を示します。


図解: クエリ文字列付きのGETメソッド

この例は富士通のサイトをJ2EEというキーで検索するものです。 クエリ文字列は 名前=値 の形式で指定します。 上の例では名前がqで値がJ2EEです。 複数の情報を送りたい場合は名前と値の組を & で区切ります。 以下はnameにtanaka、ageに28を指定するクエリ文字列の例です。


図解: クエリ文字列

このように上り情報はURLの一部として送信するので扱える情報には制約があります。 送信できるデータ量は255バイトまでですし、バイナリデータは送れません。 またURLとともにブラウザのアドレス欄に表示されてしまうなどセキュリティ上の問題点もあります。

POSTメソッド

POSTメソッドはサーバに情報を送ることが主目的なので、送信する上り情報はリクエストのボディ部に記述されます。 長さ制限はありません。 POSTメソッドではバイナリデータも送信することができます。 ここでPOSTという単語は情報を送るという意味で使われています。 本来は柱と言う意味でしたが、柱に掲示することから通知するという意味も持つようになったとのことです。

クライアントからサーバへの要求はGETメソッドかPOSTメソッドを使って行うことが多く、Webアプリケーションの開発者にとってこれらの相違を理解しておくことは重要です。 以下にGETメソッドとPOSTメソッドの相違をまとめておきます。

  GETメソッド POSTメソッド
データの種類 テキストのみ テキストおよびバイナリ
データサイズ 最大255文字 制限無し
可視性 ブラウザのURLフィールドに表示されてしまう 表示されない
上りデータ ブラウザのURL履歴に残る 残らない

通常の業務アプリケーション開発ではPOSTを使用した方がよいでしょう。 GETを使用するとセキュリティ問題だけでなく、クエリー文字列使用に起因する日本語の文字コードの文字化けなど余計な考慮が必要になります。

レスポンス

クライアントからのリクエストに対して、サーバから返されるのがレスポンスです。 レスポンスはステイタス行、ヘッダー部(メッセージヘッダー)、およびボディ部(メッセージボディ)からなっています。 ステイタス行にはリクエストに対する処理結果を示すステイタスコードが入っています。 ヘッダー部にはWebサーバの名前やデータが作成された日時などの情報が記述され、ボディ部にはリクエストで要求した内容に対応するクライアント宛の情報が記述されています。

ステイタスコードは3桁の数字で表されます。 主なコードを以下に示します。 インターネットのサイトにアクセスしたことがある方にはお馴染みの数字かも知れません。

"200": OK
"301": Moved Permanently(恒久的引っ越し)
"401": Unauthorized(非認証)
"403": Forbidden(不許可)
"404": Not Found(該当 URL 無し)
"500": Internal Server Error(サーバ内部エラー)

ステイタスコードが200のときは、ボディ部には次のような情報が入ります。

GETメソッドに対して … 要求した情報が送られる
HEADメソッドに対して… 要求した情報のヘッダー部だけが送られる
POSTメソッドに対して… POSTした情報を受け入れた結果を含んだ情報が送られる

HTMLによる呼び出し

GETメソッドやPOSTメソッドによるリクエストは、HTML(HyperText Markup Language)で作った画面から送信されます。 Webアプリの開発者にとってHTMLの知識は重要です。 とくに入力画面を作るformタグの知識は必須です。 しかし、ここではHTMLについては説明しません。 基本的なことは知っているものとして説明をします。 必要ならWebサイトで調べてください(注2)

しかしHTMLについてあまり知らなくても、これからの説明を読んで何となく判れば、当面はそれでかまいません。 もちろん実際にプログラムを作るときはちゃんと理解する必要があります。

HTMLによるhttpリクエストの送信の仕方は2通りあります。 formタグによる方法と、aタグ(アンカータグ)による方法です。 通常は前者はボタンを押す操作、後者は下線の付いた文字列をクリックする操作になります。

(注2) 役に立つHTMLの解説サイトの例です。
HTMLの概要:http://homepage.mac.com/toda/html/
HTMLタグのリファレンス:http://www.htmq.com/index.htm

formタグによる呼び出し

formタグによる呼び出しの例を示します。


図解: formタグによる呼び出し

(1)はformタグの開始です。 サーバへ渡す情報は<form>~</form>の中に書きます。 action= の後の"GreetingServlet"は呼び出すプログラムの名前です。 このプログラムの実例は後で示しましょう。

この例のようにformタグでメソッドの種類を指定しないとクライアントはデフォルトでGETメソッドを使用します。 POSTメソッドを使用したければformタグに次のように書く必要があります。


図解: POSTメソッドの指定

(2)はテキストボックスを表示するタグです。 10文字分の入力域を画面表示して、それにyourNameと言う名前をつけました。 この名前はあとでサーバのプログラムが入力したデータを読み出すときに必要です。

(3)は実行ボタンを表示するタグです。 submitとは提出すると言う意味です。 テキストボックスに入れたデータをサーバのプログラムに向けて送り出すような感覚ですね。 ボタンには送信と言う名前(ラベル)が表示されます。

HTTPリクエストの送信

クライアントはHTMLのsubmitボタンが押されると、HTTPリクエストを組み立ててactionで指定されたサーバに向け送信します。

GETメソッドでは、入力パラメーターはクエリ文字列に変換されてURLのうしろに付加されて送信されます。 前の例でテキストボックスにtanakaと入力して送信ボタンを押すと次のようなリクエストが送信されます。


図解: HTTPリクエストの送信

このようにGETメソッドの入力パラメーターはURLの後に付きますので、HTML文を用意しなくてもURLの後にクエリ文字列を手で書けば同じように動作します。 例えば検索エンジンgoogleの日本語のページのURLは http://www.google.co.jp/ ですが、googleの検索システムはsearchという名なので次のようなURLを入れると、googleのホームページ(検索文字を入力するページ)を経由せずに、aikoという文字列を直接検索した結果を表示させることができます。


図解: googleの直接検索

aタグによる呼び出し

アンカータグ(<a>)を使った呼び出しの例を示します。 以下の例ではHTML画面に送信実行と表示され、そこをクリックすると指定したプログラム(以下の例示はWebDBSrv)にリクエストを出します。 これはポイント先がサーバのプログラムであるだけで、通常のハイパーリンクによるジャンプと同じ書き方です。 この例のようにURLにはクエリ文字列を付加することができます。 アンカータグによる呼び出しでは、必ずGETメソッドが使われます。


図解: aタグによる呼び出し

確認問題

(1)

サーバにバイナリファイルを送る時に使うメソッドは何ですか。

(2)

GETメソッドでURLの後ろに置かれクエリ文字列の開始を示す文字は何ですか。

(3)

HTTPでクライアントからサーバへ送られるデータはリクエストです。 では、サーバからクライアントへ送られるデータは何と呼ばれますか。

(4)

以下のHTML文がクリックされると、どのメソッドが使われますか。
<a href="/nantara/servlet">POST</a>

(5)

GETメソッドのボディ部には通常、何が記述されますか。

(6)

HTMLの<form>タグによる呼び出しでデフォルトとして使われるメソッドは何ですか。

(7)

GETメソッドの応答としてステイタス200(OK)が返されたとき、そのボディ部には何が記述されていますか。


解答

(1) POSTメソッド
(2) ?
(3) レスポンス
(4) GETメソッド(<a>アンカータグによる呼び出しでは必ずGETメソッドが使われます)
(5) GETメソッドにはボディ部はありません
(6) GETメソッド
(7) GETで要求した情報