サーブレット&JSPの基本|HTTPリクエストとレスポンス

ブラウザとWebサーバが交わすメッセージを読み解き、Web通信の基本をつかもう。

Webページを表示するとき、ブラウザとWebサーバの間では、リクエストとレスポンスという通信が行われています。

利用者がリンクをクリックしたり、ブラウザのアドレス欄にURLを入力したりすると、ブラウザはWebサーバへ必要な情報を要求します。Webサーバはその要求を確認し、HTML、画像、処理結果などをブラウザへ返します。

この通信は、ブラウザとWebサーバが好きな形式で行っているわけではありません。通信するデータの書き方や、要求の方法、処理結果の伝え方などは、HTTPという共通のルールで決められています。

ブラウザが送る要求はHTTPリクエスト、Webサーバが返す応答はHTTPレスポンスと呼ばれます。

最初にHTTPメッセージを見ると、英単語や記号が並んでいて難しく感じるかもしれません。しかし、すべてを暗記する必要はありません。まずは、リクエストライン、ステータスライン、ヘッダ部、ボディ部という大きな構造をつかむことが大切です。

サーブレットはHTTPリクエストを受け取って処理し、HTTPレスポンスを返すプログラムです。そのため、HTTPの基本を理解しておくと、これから学ぶサーブレットの動きが見えやすくなります。

HTTPとは

HTTPはHypertext Transfer Protocolの略で、ブラウザとWebサーバがデータをやり取りするための通信ルールです。

プロトコルとは、コンピュータ同士が通信するときに使用する共通の決まりを意味します。

人同士の会話でも、同じ言語や話し方のルールがなければ、正しく意思を伝えられません。コンピュータ同士の通信も同じです。ブラウザとWebサーバがHTTPという共通のルールを使用することで、異なる会社が作ったブラウザやWebサーバでも通信できます。

HTTPでは、主に次のような内容が決められています。

項目内容
要求の方法GETやPOSTなどのリクエストメソッド
要求する対象HTMLファイルやサーブレットなどのパス
補足情報ブラウザの種類、受け取れるデータ形式、言語など
処理結果200、404、500などのステータスコード
データの種類HTML、画像、PDFなどを示すContent-Type
データ本体HTML文書、画像データ、JSONなど

Webページを1つ表示するだけでも、ブラウザとWebサーバはHTTPに従って、さまざまな情報を交換しています。

HTTP通信の基本は要求と応答

HTTP通信では、最初にブラウザがHTTPリクエストを送ります。Webサーバはそのリクエストを受け取り、HTTPレスポンスを返します。

基本的な流れは次のとおりです。

  1. 利用者がURLを入力する
  2. ブラウザがHTTPリクエストを作成する
  3. ブラウザがリクエストをWebサーバへ送る
  4. Webサーバが要求された内容を確認する
  5. WebサーバがHTMLなどのデータを用意する
  6. WebサーバがHTTPレスポンスを返す
  7. ブラウザがレスポンスを読み取って画面を表示する

HTTPでは、基本的に1つのリクエストに対して1つのレスポンスが返されます。

ただし、1つのWebページを表示する通信が1回だけとは限りません。HTMLからCSS、JavaScript、画像などが参照されている場合、ブラウザはそれぞれのファイルについて追加のHTTPリクエストを送ります。

図1:HTTPリクエストとHTTPレスポンスの全体像

この図から分かること

HTTP通信は、ブラウザから送られるHTTPリクエストと、Webサーバから返されるHTTPレスポンスで成り立っています。

HTTPリクエストには、どの方法で、どのデータを要求するのかが記述されます。HTTPレスポンスには、処理結果やデータの種類、ブラウザへ返すデータ本体などが含まれます。

ブラウザはHTTPレスポンスからHTMLを取り出し、その内容を解釈してWebページを表示します。

HTTPリクエストの全体構造

HTTPリクエストには、Webサーバへ何を要求するのかを伝える情報が含まれています。

HTTP/1.1のリクエストを、学習しやすい形にすると次のようになります。

HTTPリクエストメッセージの例

GET /guide.html HTTP/1.1
Host: www.sample-town.jp
Accept: text/html
Accept-Language: ja
User-Agent: SampleBrowser/1.0
Accept-Encoding: gzip

1行目はリクエストラインです。

2行目以降はリクエストヘッダです。リクエストヘッダには、接続先のホスト名、受け取りたいデータ形式、使用する言語、ブラウザに関する情報などが記述されます。

HTTPリクエストには、必要に応じてボディ部が付くこともあります。フォームに入力した情報をPOSTで送信する場合などは、リクエストボディにデータが格納されます。

HTTPリクエストの主な部分を整理すると、次のようになります。

部分主な内容
リクエストラインリクエストメソッド、対象、HTTPのバージョン
リクエストヘッダブラウザや受け取り可能なデータに関する補足情報
リクエストボディフォーム入力など、Webサーバへ送るデータ本体

GETでWebページを取得するときは、リクエストボディを使用しない場合が一般的です。

リクエストラインの読み方

HTTPリクエストの1行目をリクエストラインと呼びます。

リクエストラインは、主に3つの情報から構成されています。

リクエストラインの例

GET /guide.html HTTP/1.1

この1行は、次のように読み取れます。

部分名前意味
GETリクエストメソッドどの方法で要求するか
/guide.htmlリクエストターゲット何を要求するか
HTTP/1.1HTTPバージョンどのHTTP形式を使用するか

つまり、このリクエストラインは、HTTP/1.1を使って、Webサーバにある/guide.htmlをGETで取得するという意味です。

それぞれの部分は半角スペースで区切られています。

リクエストメソッドとは

リクエストメソッドは、Webサーバへどのような要求を送るのかを表します。

単にページを表示したいのか、フォームの入力情報を送りたいのか、保存された情報を更新したいのかによって、使用するリクエストメソッドが変わります。

最初に押さえておきたいのは、GETとPOSTです。

リクエストメソッド主な用途
GETWebページやデータを取得する
POST入力された情報などをWebサーバへ送る

GET

GETは、Webサーバから情報を取得するときに使われるリクエストメソッドです。

利用者がURLを入力したときや、通常のリンクをクリックしたときは、基本的にGETリクエストが送られます。

たとえば、次のような操作です。

  • 商品一覧ページを開く
  • ニュース記事を表示する
  • プロフィールページを見る
  • 検索結果を取得する

GETでは、URLの後ろに検索条件などが付く場合があります。そのため、送信した情報がブラウザのアドレス欄に表示されることがあります。

POST

POSTは、ブラウザからWebサーバへ情報を送るときによく使われるリクエストメソッドです。

たとえば、次のような操作で利用されます。

  • ログイン情報を送る
  • 会員登録フォームを送信する
  • お問い合わせ内容を送る
  • 掲示板へ文章を投稿する

サーブレットでは、GETリクエストを処理するdoGetメソッドと、POSTリクエストを処理するdoPostメソッドを使用します。

HTTPのリクエストメソッドを理解しておくと、なぜサーブレットに複数の処理メソッドがあるのかを理解しやすくなります。

リクエストターゲットとは

リクエストターゲットは、Webサーバのどのデータや処理を要求するのかを示します。

次のリクエストラインでは、/guide.htmlがリクエストターゲットです。

GET /guide.html HTTP/1.1

/guide.htmlは、Webサーバ上にあるguide.htmlというHTMLファイルを表しています。

サーブレットを利用する場合は、HTMLファイル名ではなく、サーブレットに割り当てられたURLパターンが指定されることもあります。

たとえば、次のような形です。

GET /shop/ProductList HTTP/1.1

この場合、ブラウザは固定されたHTMLファイルではなく、ProductListに対応するサーバ側の処理を要求しています。

Webサーバやサーブレットコンテナは、リクエストターゲットを確認し、どのファイルやプログラムに処理させるかを判断します。

HTTPバージョン

HTTPには複数のバージョンがあります。

代表的なものは、HTTP/1.1、HTTP/2、HTTP/3です。

バージョン主な特徴
HTTP/1.1テキスト形式のメッセージとして理解しやすく、現在も基本学習でよく使われる
HTTP/2バイナリ形式のフレームを使い、複数の通信を効率よく処理できる
HTTP/3QUICを利用し、通信開始や再接続などを効率化している

HTTP/2やHTTP/3では、実際の通信形式がHTTP/1.1とは異なります。

ただし、GETやPOST、ステータスコード、ヘッダ、Content-Typeなどの基本的な考え方は引き継がれています。そのため、最初はHTTP/1.1のメッセージ形式を使って学ぶと、HTTP通信の構造を理解しやすくなります。

リクエストヘッダの役割

リクエストラインの後ろには、リクエストヘッダが続きます。

リクエストヘッダは、ブラウザがWebサーバへ伝える補足情報です。

代表的なリクエストヘッダには次のものがあります。

ヘッダ名主な役割
Host接続先のホスト名を伝える
Acceptブラウザが受け取りたいデータ形式を伝える
Accept-Language希望する言語を伝える
User-Agentブラウザなどの情報を伝える
Accept-Encoding対応できる圧縮形式を伝える
Cookieブラウザに保存されたCookieを送る
Content-Typeリクエストボディのデータ形式を伝える
Content-Lengthリクエストボディの大きさを伝える

たとえば、Accept-Languageにjaが含まれていれば、Webサーバは日本語のページを返す判断に利用できます。

User-Agentにはブラウザや動作環境に関する情報が含まれます。ただし、Webサイト側が必ずこの情報どおりに処理するとは限りません。

HTTPレスポンスの全体構造

WebサーバはHTTPリクエストを処理すると、HTTPレスポンスを返します。

HTTP/1.1のレスポンスを、学習しやすい形にすると次のようになります。

HTTPレスポンスメッセージの例

HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
Content-Length: 168
Server: SampleServer

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>街歩きガイド</title>
</head>
<body>
  <h1>街歩きガイド</h1>
  <p>おすすめの散策コースを紹介します。</p>
</body>
</html>

1行目はステータスラインです。

2行目以降のContent-TypeやContent-Lengthなどはレスポンスヘッダです。

空行より後ろにあるHTMLがレスポンスボディです。

HTTPレスポンスは、主に次の部分で構成されます。

部分主な内容
ステータスラインHTTPのバージョンと処理結果
レスポンスヘッダデータ形式やデータ量などの補足情報
レスポンスボディHTML、画像、JSONなどのデータ本体

ヘッダ部とボディ部の間には空行があります。この空行によって、ヘッダ部が終わり、データ本体が始まることを表します。

ステータスラインの読み方

HTTPレスポンスの1行目をステータスラインと呼びます。

ステータスラインには、Webサーバがリクエストを処理した結果が記述されています。

ステータスラインの例

HTTP/1.1 200 OK

この行は次のように分けられます。

部分名前意味
HTTP/1.1HTTPバージョン使用するHTTPの形式
200ステータスコード処理結果を表す数値
OK理由句処理結果を補足する文字列

この場合は、HTTP/1.1でレスポンスを返し、リクエストを正常に処理できたことを表しています。

図2:リクエストラインとステータスラインの読み方

この図から分かること

HTTPリクエストとHTTPレスポンスの最初の1行には、それぞれ重要な情報がまとめられています。

リクエストラインを読むと、ブラウザがどの方法で、何を要求しているのかが分かります。

ステータスラインを読むと、Webサーバがリクエストをどのように処理したのかが分かります。

サーブレットの実行結果を確認するときは、画面に表示された内容だけでなく、GETやPOSTなどのリクエストメソッドと、返されたステータスコードにも注目することが大切です。

HTTPステータスコードとは

HTTPステータスコードは、Webサーバがリクエストを処理した結果を3桁の数値で表したものです。

200であれば成功、404であれば要求された対象が見つからない、500であればサーバ側で問題が発生したことを示します。

学習中によく目にする主なステータスコードは、次のとおりです。

ステータスコード意味
200 OKリクエストが正常に処理された
302 Found一時的に別のURLへ移動する
400 Bad Requestリクエストの内容に問題がある
403 Forbidden対象へのアクセスが許可されていない
404 Not Foundリクエストされた対象が見つからない
405 Method Not Allowed使用したリクエストメソッドが許可されていない
500 Internal Server ErrorWebサーバ内部でエラーが発生した

ステータスコードは、最初の数字によって大きな種類を判断できます。

範囲分類意味
100番台情報処理が継続していることなどを示す
200番台成功リクエストが正常に処理された
300番台転送別のURLへの移動などを示す
400番台クライアント側の問題URLやリクエスト内容などに問題がある
500番台サーバ側の問題Webサーバやプログラムで問題が発生した

すべてを暗記する必要はありません。まずは200、404、405、500の意味を押さえておくと、サーブレットの学習でエラーの原因を判断しやすくなります。

404 Not Foundが返される場合

404 Not Foundは、リクエストされた対象をWebサーバが見つけられなかったことを示します。

たとえば、次のような原因が考えられます。

  • URLのつづりが間違っている
  • HTMLファイルが指定された場所にない
  • サーブレットのURLパターンが間違っている
  • アプリケーション名がURLと一致していない
  • 大文字と小文字が一致していない

404が表示された場合、Webサーバそのものには接続できている可能性があります。接続できなかったのではなく、要求したファイルや処理が見つからなかったと考えると、確認する場所を絞り込めます。

405 Method Not Allowedが返される場合

405 Method Not Allowedは、要求した対象が、そのリクエストメソッドを受け付けていない場合に返されます。

たとえば、POSTだけを受け付ける処理へGETでアクセスした場合などです。

サーブレットでは、次のような組み合わせを確認します。

ブラウザからの要求サーブレット側で必要となる主な処理
GETdoGet
POSTdoPost

フォームのmethod属性がpostになっているのに、サーブレットにdoPostがない場合などは、405につながることがあります。

500 Internal Server Errorが返される場合

500 Internal Server Errorは、Webサーバやサーバ側のプログラムで問題が発生したことを示します。

サーブレットやJSPの学習では、次のような原因で発生することがあります。

  • Javaプログラムで例外が発生した
  • JSPの処理中にエラーが発生した
  • 必要なデータがnullになっていた
  • 数値に変換できない文字を変換した
  • データベース処理に失敗した
  • 設定ファイルの内容に問題がある

500が表示された場合は、ブラウザの画面だけでなく、サーバのコンソールやログに出力されたエラーメッセージを確認することが重要です。

レスポンスヘッダの役割

ステータスラインの後ろには、レスポンスヘッダが続きます。

レスポンスヘッダには、Webサーバが返すデータに関する補足情報が記述されています。

代表的なレスポンスヘッダは次のとおりです。

ヘッダ名主な役割
Content-Typeレスポンスボディのデータ形式を示す
Content-Lengthレスポンスボディの大きさを示す
ServerWebサーバに関する情報を示す
Location転送先のURLを示す
Set-Cookieブラウザへ保存させるCookieを示す
Cache-Controlキャッシュの扱い方を示す

ブラウザは、レスポンスボディを処理する前に、これらのヘッダ情報を確認します。

HTMLなのか画像なのか、文字コードは何か、別のURLへ移動する必要があるかなどを、レスポンスヘッダから判断します。

レスポンスボディとは

レスポンスボディは、Webサーバがブラウザへ返すデータ本体です。

HTMLページを返す場合は、レスポンスボディにHTML文書が入ります。画像を返す場合は画像データ、PDFを返す場合はPDFデータが入ります。

レスポンスボディの内容は、必ずHTMLとは限りません。

Webサーバは、次のようなさまざまなデータを返せます。

  • HTML
  • CSS
  • JavaScript
  • JPEG画像
  • PNG画像
  • PDF
  • 動画
  • 音声
  • JSON
  • テキスト

ブラウザは、受け取ったデータの種類に応じて処理方法を変えます。その判断に使われる重要な情報がContent-Typeです。

Content-Typeとは

Content-Typeは、HTTPメッセージのボディ部に入っているデータの種類を示すヘッダです。

レスポンスでContent-Typeが指定されていると、ブラウザはデータ本体をどのように処理すればよいかを判断できます。

宅配便で考えると、箱の中身そのものがレスポンスボディで、伝票に書かれた品名がContent-Typeに近い役割を持っています。

品名を見れば、中身を開ける前に、食品なのか書籍なのか精密機器なのかを判断できます。ブラウザも同じように、Content-Typeを先に確認してから、後ろに続くデータ本体を処理します。

HTMLを返すContent-Type

HTML文書をブラウザへ返す場合は、Content-Typeにtext/htmlを指定します。

日本語をUTF-8で扱う場合は、charset=UTF-8も指定します。

HTMLをレスポンスするContent-Typeの例

Content-Type: text/html; charset=UTF-8

それぞれの意味は次のとおりです。

指定意味
text/htmlデータ本体がHTMLである
charset=UTF-8HTMLの文字コードがUTF-8である

charsetの指定が実際の文字コードと一致していない場合、日本語が文字化けする可能性があります。

JSPやサーブレットからHTMLを返すときも、Content-Typeと文字コードを適切に設定する必要があります。

JPEG画像を返すContent-Type

JPEG画像をブラウザへ返す場合は、Content-Typeにimage/jpegを指定します。

JPEG画像をレスポンスするContent-Typeの例

Content-Type: image/jpeg

この指定を確認したブラウザは、レスポンスボディをHTMLとして読むのではなく、JPEG画像として処理します。

主なContent-Typeには次のようなものがあります。

Content-Typeデータの種類
text/htmlHTML文書
text/cssCSS
text/plain通常のテキスト
application/javascriptJavaScript
application/jsonJSON
image/jpegJPEG画像
image/pngPNG画像
application/pdfPDF

Content-Typeが誤っていると、データ本体が正しくても、ブラウザが期待した方法で表示できないことがあります。

図3:Content-Typeでデータの種類を伝える

この図から分かること

Webサーバが返すデータは、HTMLだけではありません。

ブラウザは、レスポンスヘッダのContent-Typeを確認し、レスポンスボディをHTML、画像、PDFなどのどの形式として扱うのかを判断します。

Content-Typeがtext/htmlならHTMLとして解析し、image/jpegならJPEG画像として表示します。

サーブレットからレスポンスを返すときも、生成するデータに合ったContent-Typeを設定する必要があります。

HTTPのヘッダとHTMLのhead要素は別のもの

HTTPレスポンスのヘッダ部と、HTML文書のhead要素は名前が似ていますが、別のものです。

対象含まれる場所主な役割
HTTPヘッダHTTPリクエストやHTTPレスポンス通信データに関する補足情報を伝える
HTMLのhead要素HTML文書ページタイトルや文字コードなどを記述する
HTTPボディHTTPメッセージHTMLや画像などのデータ本体を格納する
HTMLのbody要素HTML文書ブラウザに表示するページ本文を記述する

HTTPレスポンスのボディ部にHTML文書が格納され、そのHTML文書の中にhead要素とbody要素があります。

構造を整理すると、次のようになります。

  1. HTTPレスポンスにヘッダ部がある
  2. HTTPレスポンスにボディ部がある
  3. ボディ部の中にHTML文書が入る
  4. HTML文書の中にhead要素とbody要素がある

同じヘッダやボディという言葉が使われますが、HTTPメッセージの構造とHTML文書の構造を混同しないようにしましょう。

サーブレットとHTTPリクエスト

サーブレットは、HTTPリクエストを受け取って動作します。

ブラウザから送られたリクエストの内容は、サーブレット内でHttpServletRequestというオブジェクトを通じて扱います。

HttpServletRequestからは、次のような情報を取得できます。

  • フォームに入力された値
  • リクエストメソッド
  • リクエストされたURL
  • リクエストヘッダ
  • Cookie
  • セッションに関する情報

たとえば、ログイン画面で入力されたユーザー名やパスワードも、HTTPリクエストに含めて送られます。サーブレットはそれらの値を取り出し、ログインできるかどうかを判定します。

サーブレットとHTTPレスポンス

サーブレットは処理結果をHTTPレスポンスとしてブラウザへ返します。

レスポンスの内容は、HttpServletResponseというオブジェクトを通じて設定します。

サーブレットからレスポンスを返すときには、主に次のような処理を行います。

  • Content-Typeを設定する
  • 文字コードを設定する
  • ステータスコードを設定する
  • レスポンスボディへHTMLなどを書き出す
  • 別のURLへの転送を指示する
  • Cookieを追加する

JSPを使う場合は、サーブレットが処理結果をJSPへ渡し、JSPがHTMLを生成します。生成されたHTMLはHTTPレスポンスのボディ部に格納され、ブラウザへ送られます。

エラーを調べるときはHTTPのどこを見るか

Webアプリケーションが想定どおりに動作しないときは、HTTPリクエストとHTTPレスポンスを意識すると原因を整理しやすくなります。

発生している問題確認する内容
正しい画面へ移動しないリクエストターゲットやURL
フォームの値を取得できないGETかPOSTか、入力項目の名前
404が表示されるURLやサーブレットの対応付け
405が表示されるリクエストメソッドとdoGet、doPost
500が表示されるサーバ側のJavaプログラムやログ
日本語が文字化けするContent-Typeと文字コード
HTMLではなく文字列として表示されるContent-Typeの指定
画像が表示されない画像のURLとレスポンスのContent-Type

ブラウザの開発者ツールには、ネットワーク通信を確認する機能があります。

そこでは、送信されたリクエストメソッド、URL、リクエストヘッダ、ステータスコード、レスポンスヘッダなどを確認できます。

すべての項目を最初から理解する必要はありません。まずは、次の3点を見る習慣を付けるとよいでしょう。

  • GETとPOSTのどちらが送られたか
  • どのURLがリクエストされたか
  • どのステータスコードが返されたか

HTTPリクエストとHTTPレスポンスは、サーブレットとJSPによるWebアプリケーション開発の中心にあるしくみです。

ブラウザはHTTPリクエストで処理を要求し、WebサーバやサーブレットはHTTPレスポンスで処理結果を返します。リクエストライン、ステータスライン、ヘッダ部、ボディ部の役割を意識すると、Webアプリケーションの動きやエラーの原因を理解しやすくなります。