第5章: リクエストとレスポンスの処理
HTTPリクエストとレスポンスの理解と処理
この章で学ぶこと
- HTTPリクエストとレスポンスの基本概念と仕組み
- requestオブジェクトを使用したデータ取得方法
- responseオブジェクトを使用した出力制御
- GETとPOSTメソッドの違いと適切な使い分け
- フォームデータの処理技術と日本語文字化け対策
5.1 HTTPリクエストとレスポンスの基本
Webアプリケーション開発において、HTTPリクエストとレスポンスの理解は非常に重要です。HTTPは「HyperText Transfer Protocol」の略で、WebブラウザとWebサーバー間でデータをやり取りするためのプロトコル(通信規約)です。
sequenceDiagram
participant Browser as Webブラウザ
participant Server as Webサーバー
participant JSP as JSPページ
Browser->>Server: HTTPリクエスト送信
Note over Browser,Server: URL、パラメータ、ヘッダー情報含む
Server->>JSP: リクエスト処理依頼
JSP->>JSP: ビジネスロジック実行
JSP->>Server: HTML生成・返却
Server->>Browser: HTTPレスポンス送信
Note over Server,Browser: HTML、ヘッダー、ステータスコード含む
HTTPリクエストの構成要素
- リクエストライン: HTTPメソッド、URL、HTTPバージョン
- ヘッダーフィールド: Content-Type、User-Agent、Cookieなど
- メッセージボディ: POSTメソッドで送信されるデータ
HTTPレスポンスの構成要素
- ステータスライン: HTTPバージョン、ステータスコード、理由句
- ヘッダーフィールド: Content-Type、Set-Cookie、Cache-Controlなど
- メッセージボディ: HTML、JSON、画像データなど
5.2 requestオブジェクトによるデータ取得
JSPでは、request
オブジェクト(HttpServletRequestのインスタンス)を使用して、クライアントから送信されたデータにアクセスできます。このオブジェクトは、JSPの暗黙的オブジェクトの1つです。
主要なrequestオブジェクトのメソッド
メソッド | 説明 | 戻り値 |
---|---|---|
getParameter(String name) |
指定したパラメータの値を取得 | String |
getParameterValues(String name) |
同名の複数パラメータを配列で取得 | String[] |
getParameterNames() |
全パラメータ名を取得 | Enumeration<String> |
getMethod() |
HTTPメソッドを取得 | String |
getHeader(String name) |
指定したヘッダーの値を取得 | String |
getRequestURI() |
リクエストURIを取得 | String |
実習 5-1: リクエストパラメータの取得
フォームから送信されたデータをJSPで受け取り表示するプログラムを作成します。
手順1: HTMLフォームの作成(form.html)
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>ユーザー情報入力フォーム</title>
</head>
<body>
<h2>ユーザー情報入力</h2>
<form action="processForm.jsp" method="post">
<p>
名前: <input type="text" name="username" required>
</p>
<p>
年齢: <input type="number" name="age" min="0" max="150">
</p>
<p>
趣味:
<input type="checkbox" name="hobby" value="読書"> 読書
<input type="checkbox" name="hobby" value="映画"> 映画
<input type="checkbox" name="hobby" value="スポーツ"> スポーツ
</p>
<p>
<input type="submit" value="送信">
</p>
</form>
</body>
</html>
手順2: JSPでのデータ処理(processForm.jsp)
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" %>
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>フォーム処理結果</title>
</head>
<body>
<h2>入力データの確認</h2>
<%
// 文字エンコーディングの設定(日本語文字化け対策)
request.setCharacterEncoding("UTF-8");
// パラメータの取得
String username = request.getParameter("username");
String ageStr = request.getParameter("age");
String[] hobbies = request.getParameterValues("hobby");
// リクエスト情報の表示
String method = request.getMethod();
String uri = request.getRequestURI();
%>
<table border="1">
<tr>
<th>項目</th>
<th>値</th>
</tr>
<tr>
<td>名前</td>
<td><%= username != null ? username : "未入力" %></td>
</tr>
<tr>
<td>年齢</td>
<td><%= ageStr != null ? ageStr + "歳" : "未入力" %></td>
</tr>
<tr>
<td>趣味</td>
<td>
<%
if (hobbies != null) {
for (String hobby : hobbies) {
out.println(hobby + " ");
}
} else {
out.println("選択なし");
}
%>
</td>
</tr>
<tr>
<td>HTTPメソッド</td>
<td><%= method %></td>
</tr>
<tr>
<td>リクエストURI</td>
<td><%= uri %></td>
</tr>
</table>
<p><a href="form.html">入力フォームに戻る</a></p>
</body>
</html>
期待される結果
フォームで入力したデータがテーブル形式で表示され、HTTPメソッドとリクエストURIも確認できます。
5.3 GETとPOSTメソッドの理解と使い分け
HTTPには様々なメソッドがありますが、Webアプリケーション開発では主にGETとPOSTメソッドを使用します。それぞれに特徴と適切な使用場面があります。
flowchart TD
A[HTTP通信] --> B[GETメソッド]
A --> C[POSTメソッド]
B --> D["データ取得・表示
(リソースの読み取り)"] B --> E["URLにパラメータ付与
(クエリ文字列)"] B --> F["ブックマーク可能
(冪等性あり)"] C --> G["データ送信・更新
(リソースの変更)"] C --> H["リクエストボディに
パラメータ格納"] C --> I["機密情報送信
(冪等性なし)"]
(リソースの読み取り)"] B --> E["URLにパラメータ付与
(クエリ文字列)"] B --> F["ブックマーク可能
(冪等性あり)"] C --> G["データ送信・更新
(リソースの変更)"] C --> H["リクエストボディに
パラメータ格納"] C --> I["機密情報送信
(冪等性なし)"]
GETメソッドの特徴
- 用途: データの取得、検索結果の表示
- パラメータ: URLのクエリ文字列として送信
- データサイズ制限: URLの長さ制限(通常2048文字程度)
- セキュリティ: URLに情報が表示されるため機密情報には不適切
- キャッシュ: ブラウザやプロキシでキャッシュされる
- 冪等性: 何度実行しても同じ結果(副作用なし)
POSTメソッドの特徴
- 用途: データの送信、更新、削除
- パラメータ: リクエストボディ内に格納
- データサイズ制限: サーバーの設定により決まる(通常数MB程度)
- セキュリティ: URLに表示されないため相対的に安全
- キャッシュ: 通常キャッシュされない
- 冪等性: 実行のたびに状態が変化する可能性
実習 5-2: GETとPOSTの動作比較
同じデータを GETとPOSTで送信し、動作の違いを確認します。
手順1: 両メソッド対応フォーム(compare.html)
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>GET vs POST比較</title>
</head>
<body>
<h2>GETとPOSTメソッドの比較</h2>
<h3>GETメソッドでの送信</h3>
<form action="methodCompare.jsp" method="get">
<p>
検索キーワード: <input type="text" name="keyword" value="Java">
</p>
<p>
カテゴリ:
<select name="category">
<option value="programming">プログラミング</option>
<option value="database">データベース</option>
<option value="web">Webテクノロジー</option>
</select>
</p>
<p>
<input type="submit" value="GET送信">
</p>
</form>
<h3>POSTメソッドでの送信</h3>
<form action="methodCompare.jsp" method="post">
<p>
検索キーワード: <input type="text" name="keyword" value="Java">
</p>
<p>
カテゴリ:
<select name="category">
<option value="programming">プログラミング</option>
<option value="database">データベース</option>
<option value="web">Webテクノロジー</option>
</select>
</p>
<p>
<input type="submit" value="POST送信">
</p>
</form>
</body>
</html>
手順2: メソッド比較処理(methodCompare.jsp)
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" %>
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>メソッド比較結果</title>
</head>
<body>
<h2>HTTPメソッド比較結果</h2>
<%
// 文字エンコーディング設定
request.setCharacterEncoding("UTF-8");
// リクエスト情報の取得
String method = request.getMethod();
String keyword = request.getParameter("keyword");
String category = request.getParameter("category");
String queryString = request.getQueryString();
%>
<table border="1" cellpadding="5">
<tr>
<th>項目</th>
<th>値</th>
<th>説明</th>
</tr>
<tr>
<td>HTTPメソッド</td>
<td><%= method %></td>
<td>使用された通信方式</td>
</tr>
<tr>
<td>キーワード</td>
<td><%= keyword %></td>
<td>入力された検索語</td>
</tr>
<tr>
<td>カテゴリ</td>
<td><%= category %></td>
<td>選択されたカテゴリ</td>
</tr>
<tr>
<td>クエリ文字列</td>
<td><%= queryString != null ? queryString : "なし" %></td>
<td>GETの場合のみURLに付加される</td>
</tr>
</table>
<h3>メソッドの特徴</h3>
<%
if ("GET".equals(method)) {
%>
<div style="background-color: #e7f3ff; padding: 10px; border-left: 4px solid #2196F3;">
<h4>GETメソッドの特徴</h4>
<ul>
<li>URLにパラメータが表示されています(上記のクエリ文字列参照)</li>
<li>ブックマークや履歴に保存可能</li>
<li>検索機能など、データ取得に適している</li>
<li>機密情報の送信には向かない</li>
</ul>
</div>
<%
} else if ("POST".equals(method)) {
%>
<div style="background-color: #fff3e0; padding: 10px; border-left: 4px solid #ff9800;">
<h4>POSTメソッドの特徴</h4>
<ul>
<li>URLにパラメータが表示されません(クエリ文字列がnull)</li>
<li>大量のデータ送信が可能</li>
<li>ユーザー登録、データ更新などに適している</li>
<li>相対的にセキュアな通信</li>
</ul>
</div>
<%
}
%>
<p><a href="compare.html">比較フォームに戻る</a></p>
</body>
</html>
期待される結果
GETでは URL にパラメータが表示され、POSTでは表示されない違いを確認できます。
5.4 responseオブジェクトによる出力制御
response
オブジェクト(HttpServletResponseのインスタンス)を使用して、クライアントへのレスポンスを制御できます。
主要なresponseオブジェクトのメソッド
メソッド | 説明 | 用途 |
---|---|---|
setContentType(String type) |
レスポンスのコンテンツタイプを設定 | HTML、JSON、PDFなどの出力形式指定 |
setCharacterEncoding(String charset) |
文字エンコーディングを設定 | 日本語文字化け対策 |
sendRedirect(String location) |
指定URLへのリダイレクト | ページ遷移制御 |
setHeader(String name, String value) |
レスポンスヘッダーを設定 | キャッシュ制御、セキュリティ設定 |
addCookie(Cookie cookie) |
クッキーをレスポンスに追加 | ユーザー状態の保存 |
実習 5-3: レスポンス制御の実践
responseオブジェクトを使用してリダイレクトとヘッダー制御を行います。
手順1: ログインフォーム(login.html)
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>ログインフォーム</title>
</head>
<body>
<h2>ユーザーログイン</h2>
<form action="authenticate.jsp" method="post">
<p>
ユーザー名: <input type="text" name="username" required>
</p>
<p>
パスワード: <input type="password" name="password" required>
</p>
<p>
<input type="submit" value="ログイン">
</p>
</form>
</body>
</html>
手順2: 認証処理(authenticate.jsp)
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" %>
<%
// 文字エンコーディング設定
request.setCharacterEncoding("UTF-8");
// パラメータ取得
String username = request.getParameter("username");
String password = request.getParameter("password");
// 簡易認証ロジック(実際の開発では暗号化されたパスワードを使用)
boolean isAuthenticated = false;
if ("admin".equals(username) && "password123".equals(password)) {
isAuthenticated = true;
}
if (isAuthenticated) {
// 認証成功時の処理
// 1. キャッシュ無効化ヘッダーの設定
response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
response.setHeader("Pragma", "no-cache");
response.setDateHeader("Expires", 0);
// 2. セキュリティヘッダーの設定
response.setHeader("X-Content-Type-Options", "nosniff");
response.setHeader("X-Frame-Options", "DENY");
// 3. 成功ページへリダイレクト
response.sendRedirect("welcome.jsp?user=" + java.net.URLEncoder.encode(username, "UTF-8"));
} else {
// 認証失敗時の処理
// 1. コンテンツタイプ設定
response.setContentType("text/html; charset=UTF-8");
// 2. ステータスコード設定(認証失敗)
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
// 3. エラーメッセージ出力
%>
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>ログインエラー</title>
</head>
<body>
<h2>ログインに失敗しました</h2>
<div style="background-color: #ffebee; padding: 15px; border: 1px solid #f44336; border-radius: 5px;">
<p><strong>エラー:</strong>ユーザー名またはパスワードが正しくありません。</p>
<p>正しい認証情報を入力してください。</p>
</div>
<h3>認証情報確認</h3>
<p>入力されたユーザー名: <%= username %></p>
<p>HTTPステータス: <%= response.getStatus() %> (Unauthorized)</p>
<p><a href="login.html">ログインページに戻る</a></p>
<div style="background-color: #e3f2fd; padding: 10px; margin-top: 20px;">
<h4>デモ用認証情報</h4>
<p>ユーザー名: admin</p>
<p>パスワード: password123</p>
</div>
</body>
</html>
<%
}
%>
手順3: ウェルカムページ(welcome.jsp)
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" %>
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>ウェルカムページ</title>
</head>
<body>
<h2>ログイン成功!</h2>
<%
String user = request.getParameter("user");
if (user != null) {
%>
<div style="background-color: #e8f5e8; padding: 15px; border: 1px solid #4caf50; border-radius: 5px;">
<h3>ようこそ、<%= user %>さん!</h3>
<p>正常にログインが完了しました。</p>
</div>
<h3>セッション情報</h3>
<ul>
<li>ユーザー名: <%= user %></li>
<li>ログイン時刻: <%= new java.util.Date() %></li>
<li>セッションID: <%= session.getId() %></li>
</ul>
<%
} else {
// 直接アクセスされた場合
response.sendRedirect("login.html");
}
%>
<p><a href="login.html">ログアウト</a></p>
</body>
</html>
期待される結果
- 正しい認証情報(admin/password123)でログイン成功
- 間違った認証情報でエラーページ表示
- 各種レスポンスヘッダーが適切に設定される
5.5 日本語文字化け対策
日本語を含むWebアプリケーションでは、文字エンコーディングの適切な設定が重要です。UTF-8を標準として統一し、リクエストとレスポンス両方で適切に設定する必要があります。
文字化けの主な原因
- リクエストとレスポンスで異なる文字エンコーディングを使用
- ファイル保存時の文字エンコーディングが不適切
- データベースとの文字エンコーディング不一致
- サーバー(Tomcat)の設定が不適切
文字エンコーディング設定のベストプラクティス
1. JSPページでの設定
<%-- ページディレクティブで設定 --%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" %>
<%
// リクエストの文字エンコーディング設定
request.setCharacterEncoding("UTF-8");
// レスポンスの文字エンコーディング設定
response.setContentType("text/html; charset=UTF-8");
response.setCharacterEncoding("UTF-8");
%>
2. HTMLメタタグでの設定
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>日本語対応ページ</title>
</head>
3. フォームでの設定
<form action="process.jsp" method="post" accept-charset="UTF-8">
<!-- accept-charset属性でエンコーディングを明示 -->
<input type="text" name="japanese_text">
<input type="submit" value="送信">
</form>
理解度確認クイズ
-
HTTPリクエストとレスポンスについて
HTTPリクエストの主要な構成要素を3つ挙げて、それぞれの役割を説明してください。 -
GETとPOSTの使い分け
以下の機能を実装する場合、GETとPOSTのどちらを使用すべきか理由とともに答えてください:- 検索機能
- ユーザー登録
- 商品詳細表示
- パスワード変更
-
requestオブジェクトのメソッド
複数の値を持つ同名のパラメータ(チェックボックスなど)を取得するには、どのメソッドを使用しますか?また、その戻り値の型は何ですか? -
responseオブジェクトの活用
ログイン成功後にダッシュボードページへリダイレクトするJSPコードを書いてください。 -
文字エンコーディング対策
日本語の文字化けを防ぐために、JSPページで設定すべき3つの項目を挙げてください。
5.6 まとめ
この章では、JSPにおけるHTTPリクエストとレスポンスの処理について詳しく学習しました。
重要なポイント
- HTTPの基本理解: リクエストとレスポンスの構造と役割
- requestオブジェクト: パラメータ取得とリクエスト情報の活用
- responseオブジェクト: レスポンス制御とリダイレクト処理
- メソッドの使い分け: GETとPOSTの特徴と適切な使用場面
- 文字エンコーディング: UTF-8による日本語文字化け対策