はじめに
Servlet/JSP入門の第5回は セッション管理とCookie です。
HTTPは本来「ステートレス(状態を持たない)」なプロトコルです。しかし、ログイン状態の保持やショッピングカートなど、ユーザーの状態を複数のリクエストにわたって管理する必要があります。この課題を解決するのがセッションとCookieです。
第5回で学ぶこと
- HTTPがステートレスであることの意味
- HttpSessionの基本操作
- セッションのライフサイクルとタイムアウト
- Cookieの基本操作
- セッションとCookieの違い
- ログイン/ログアウト機能の実装
1. HTTPはステートレス
ステートレスとは?
HTTPでは、1回のリクエストとレスポンスが完結すると、サーバーはクライアントの情報を忘れます。
【リクエスト1】ログイン → サーバー「OK、ログイン成功」
【リクエスト2】マイページ表示 → サーバー「あなた誰?」 ← 前のリクエストの情報がない!
なぜセッション管理が必要か
| やりたいこと | なぜ状態管理が必要? |
|---|---|
| ログイン状態の保持 | ページ移動のたびにログインし直すのは不便 |
| ショッピングカート | カートの中身を複数ページにわたって保持したい |
| 入力ウィザード | 複数画面にわたる入力を一時保存したい |
| ユーザー設定 | 言語やテーマなどの設定を保持したい |
解決策
┌────────────┐ ┌──────────────────┐
│ ブラウザ │ ←── セッションID ──→ │ サーバー │
│ │ (Cookieで送受信) │ セッション領域 │
│ │ │ ├ ユーザー名: 田中 │
│ │ │ ├ カート: [商品A] │
│ │ │ └ ログイン: true │
└────────────┘ └──────────────────┘
サーバー側に セッション領域 を作り、クライアントには セッションID だけを渡します。以降のリクエストでは、セッションIDをもとにサーバーがユーザーを識別します。
2. HttpSession の基本
セッションの取得と操作
// セッションを取得(なければ新規作成)
HttpSession session = request.getSession();
// セッションを取得(なければnullを返す)
HttpSession session = request.getSession(false);
主要メソッド
| メソッド | 説明 | 例 |
|---|---|---|
setAttribute(key, value) |
セッションにデータを保存 | session.setAttribute("user", "田中") |
getAttribute(key) |
セッションからデータを取得 | session.getAttribute("user") |
removeAttribute(key) |
セッションからデータを削除 | session.removeAttribute("user") |
invalidate() |
セッションを無効化(全データ削除) | session.invalidate() |
getId() |
セッションIDを取得 | session.getId() |
isNew() |
新規セッションかどうか | session.isNew() |
getCreationTime() |
セッション作成時刻 | session.getCreationTime() |
getLastAccessedTime() |
最終アクセス時刻 | session.getLastAccessedTime() |
セッションの基本的な使い方
SessionDemoServlet.java
package servlet;
import java.io.IOException;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
@WebServlet("/session-demo")
public class SessionDemoServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
String userName = request.getParameter("userName");
// セッションにユーザー名を保存
HttpSession session = request.getSession();
session.setAttribute("userName", userName);
// アクセスカウントを更新
Integer count = (Integer) session.getAttribute("accessCount");
if (count == null) {
count = 1;
} else {
count++;
}
session.setAttribute("accessCount", count);
response.sendRedirect(request.getContextPath() + "/session-info");
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.getRequestDispatcher("/WEB-INF/session-form.jsp").forward(request, response);
}
}
SessionInfoServlet.java
package servlet;
import java.io.IOException;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
@WebServlet("/session-info")
public class SessionInfoServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
HttpSession session = request.getSession(false);
if (session != null) {
request.setAttribute("sessionId", session.getId());
request.setAttribute("userName", session.getAttribute("userName"));
request.setAttribute("accessCount", session.getAttribute("accessCount"));
request.setAttribute("isNew", session.isNew());
}
request.getRequestDispatcher("/WEB-INF/session-info.jsp").forward(request, response);
}
}
3. セッションのライフサイクルとタイムアウト
セッションのライフサイクル
作成 利用中 破棄
│ │ │
├─ getSession() ───→ ├─ setAttribute() ──→ ├─ invalidate()
│ で新規作成 ├─ getAttribute() │ で明示的に破棄
│ ├─ removeAttribute() ├─ タイムアウト
│ │ │ で自動破棄
タイムアウトの設定
セッションは一定時間アクセスがないと自動的に破棄されます。
Javaコードで設定
HttpSession session = request.getSession();
// タイムアウトを30分に設定(秒単位)
session.setMaxInactiveInterval(30 * 60);
web.xml で設定(アプリケーション全体)
<web-app>
<session-config>
<!-- タイムアウトを30分に設定(分単位) -->
<session-timeout>30</session-timeout>
</session-config>
</web-app>
| 設定方法 | 単位 | 適用範囲 |
|---|---|---|
setMaxInactiveInterval() |
秒 | 個別のセッション |
web.xml の session-timeout
|
分 | アプリ全体 |
4. Cookie の基本
Cookieとは?
Cookieは、ブラウザ側 にデータを保存する仕組みです。サーバーがレスポンスでCookieを送り、ブラウザは次回以降のリクエストに自動的にCookieを付けて送信します。
【初回アクセス】
ブラウザ → リクエスト → サーバー
ブラウザ ← レスポンス + Set-Cookie: theme=dark ← サーバー
【2回目以降】
ブラウザ → リクエスト + Cookie: theme=dark → サーバー
Cookieの作成と送信
// Cookieを作成
Cookie cookie = new Cookie("theme", "dark");
// 有効期限を設定(秒単位、7日間)
cookie.setMaxAge(7 * 24 * 60 * 60);
// パスを設定(アプリ全体で有効)
cookie.setPath("/");
// レスポンスにCookieを追加
response.addCookie(cookie);
Cookieの読み取り
Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (Cookie cookie : cookies) {
if ("theme".equals(cookie.getName())) {
String theme = cookie.getValue();
// themeの値を使用
}
}
}
Cookieの削除
Cookie cookie = new Cookie("theme", "");
cookie.setMaxAge(0); // 有効期限を0にすると削除される
cookie.setPath("/");
response.addCookie(cookie);
Cookie設定の主要メソッド
| メソッド | 説明 |
|---|---|
setMaxAge(秒) |
有効期限(0で削除、負の値でブラウザ終了時に削除) |
setPath(パス) |
Cookieが有効なパス |
setSecure(true) |
HTTPS通信のみで送信 |
setHttpOnly(true) |
JavaScriptからのアクセスを禁止 |
Cookieの実践例:テーマ設定
ThemeServlet.java
package servlet;
import java.io.IOException;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
@WebServlet("/theme")
public class ThemeServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 現在のテーマをCookieから取得
String currentTheme = "light"; // デフォルト
Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (Cookie cookie : cookies) {
if ("theme".equals(cookie.getName())) {
currentTheme = cookie.getValue();
}
}
}
request.setAttribute("currentTheme", currentTheme);
request.getRequestDispatcher("/WEB-INF/theme.jsp").forward(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String theme = request.getParameter("theme");
// Cookieにテーマを保存(30日間有効)
Cookie cookie = new Cookie("theme", theme);
cookie.setMaxAge(30 * 24 * 60 * 60);
cookie.setPath("/");
response.addCookie(cookie);
response.sendRedirect(request.getContextPath() + "/theme");
}
}
WEB-INF/theme.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<%
String theme = (String) request.getAttribute("currentTheme");
String bgColor = "light".equals(theme) ? "#ffffff" : "#333333";
String textColor = "light".equals(theme) ? "#333333" : "#ffffff";
%>
<!DOCTYPE html>
<html>
<head><title>テーマ設定</title></head>
<body style="background-color: <%= bgColor %>; color: <%= textColor %>; padding: 20px;">
<h1>テーマ設定</h1>
<p>現在のテーマ: <strong><%= theme %></strong></p>
<form action="<%= request.getContextPath() %>/theme" method="post">
<select name="theme">
<option value="light" <%= "light".equals(theme) ? "selected" : "" %>>ライト</option>
<option value="dark" <%= "dark".equals(theme) ? "selected" : "" %>>ダーク</option>
</select>
<button type="submit">変更</button>
</form>
</body>
</html>
5. セッションとCookieの違い
| 項目 | セッション(HttpSession) | Cookie |
|---|---|---|
| データの保存先 | サーバー側 | ブラウザ側 |
| 保存できるデータ | Javaオブジェクト何でも | 文字列のみ |
| データ量の制限 | サーバーメモリ次第 | 1つ約4KB |
| セキュリティ | 高い(サーバーに保存) | 低い(改ざんの可能性あり) |
| 有効期限 | サーバーのタイムアウト設定 | 自由に設定可能 |
| 用途 | ログイン状態、カート | ユーザー設定、訪問履歴 |
使い分けの基準
機密情報(ログイン情報、個人データ)→ セッション
理由:サーバー側に保存されるため安全
軽量な設定(テーマ、言語、表示件数)→ Cookie
理由:サーバーの負荷が少なく、長期保存が可能
6. ログイン/ログアウト機能の実装
セッション管理の典型的な例として、ログイン/ログアウト機能を実装しましょう。
LoginServlet.java
package servlet;
import java.io.IOException;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// すでにログイン済みならマイページへ
HttpSession session = request.getSession(false);
if (session != null && session.getAttribute("loginUser") != null) {
response.sendRedirect(request.getContextPath() + "/mypage");
return;
}
request.getRequestDispatcher("/WEB-INF/login.jsp").forward(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
String userId = request.getParameter("userId");
String password = request.getParameter("password");
// 認証チェック(実際のアプリではDBで確認する)
if ("admin".equals(userId) && "password123".equals(password)) {
// ログイン成功
HttpSession session = request.getSession();
session.setAttribute("loginUser", userId);
session.setMaxInactiveInterval(30 * 60); // 30分
response.sendRedirect(request.getContextPath() + "/mypage");
} else {
// ログイン失敗
request.setAttribute("error", "ユーザーIDまたはパスワードが正しくありません。");
request.getRequestDispatcher("/WEB-INF/login.jsp").forward(request, response);
}
}
}
MyPageServlet.java
package servlet;
import java.io.IOException;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
@WebServlet("/mypage")
public class MyPageServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// ログインチェック
HttpSession session = request.getSession(false);
if (session == null || session.getAttribute("loginUser") == null) {
response.sendRedirect(request.getContextPath() + "/login");
return;
}
String loginUser = (String) session.getAttribute("loginUser");
request.setAttribute("loginUser", loginUser);
request.getRequestDispatcher("/WEB-INF/mypage.jsp").forward(request, response);
}
}
LogoutServlet.java
package servlet;
import java.io.IOException;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
@WebServlet("/logout")
public class LogoutServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// セッションを無効化
HttpSession session = request.getSession(false);
if (session != null) {
session.invalidate();
}
// ログイン画面にリダイレクト
response.sendRedirect(request.getContextPath() + "/login");
}
}
WEB-INF/login.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<!DOCTYPE html>
<html>
<head><title>ログイン</title></head>
<body>
<h1>ログイン</h1>
<% if (request.getAttribute("error") != null) { %>
<p style="color: red;"><%= request.getAttribute("error") %></p>
<% } %>
<form action="<%= request.getContextPath() %>/login" method="post">
<table>
<tr>
<td><label>ユーザーID:</label></td>
<td><input type="text" name="userId" required /></td>
</tr>
<tr>
<td><label>パスワード:</label></td>
<td><input type="password" name="password" required /></td>
</tr>
<tr>
<td></td>
<td><button type="submit">ログイン</button></td>
</tr>
</table>
</form>
<p>テスト用アカウント: admin / password123</p>
</body>
</html>
WEB-INF/mypage.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<!DOCTYPE html>
<html>
<head><title>マイページ</title></head>
<body>
<h1>マイページ</h1>
<p>ようこそ、<strong><%= request.getAttribute("loginUser") %></strong> さん!</p>
<p>セッションID: <%= session.getId() %></p>
<p><a href="<%= request.getContextPath() %>/logout">ログアウト</a></p>
</body>
</html>
処理フロー
【ログイン前】
ブラウザ → /mypage → セッションなし → /login にリダイレクト
【ログイン処理】
ブラウザ → POST /login → 認証成功 → セッションにユーザー情報を保存 → /mypage にリダイレクト
ブラウザ → POST /login → 認証失敗 → エラーメッセージ付きでログイン画面に戻る
【ログイン後】
ブラウザ → /mypage → セッションあり → マイページを表示
【ログアウト】
ブラウザ → /logout → セッション無効化 → /login にリダイレクト
練習問題
問題1:訪問カウンター ⭐
セッションを使って、ユーザーのページ訪問回数を数えるServletを作成してください。
- URLパターン:
/visit-counter - アクセスするたびにカウントが増加
- 現在の訪問回数とセッションIDを表示
模範解答
VisitCounterServlet.java
package servlet;
import java.io.IOException;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
@WebServlet("/visit-counter")
public class VisitCounterServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
HttpSession session = request.getSession();
Integer count = (Integer) session.getAttribute("visitCount");
if (count == null) {
count = 1;
} else {
count++;
}
session.setAttribute("visitCount", count);
request.setAttribute("visitCount", count);
request.setAttribute("sessionId", session.getId());
request.getRequestDispatcher("/WEB-INF/visit-counter.jsp").forward(request, response);
}
}
WEB-INF/visit-counter.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<!DOCTYPE html>
<html>
<head><title>訪問カウンター</title></head>
<body>
<h1>訪問カウンター</h1>
<p>あなたの訪問回数: <strong><%= request.getAttribute("visitCount") %></strong> 回</p>
<p>セッションID: <%= request.getAttribute("sessionId") %></p>
<p><a href="<%= request.getContextPath() %>/visit-counter">もう一度アクセス</a></p>
</body>
</html>
問題2:Cookieでユーザー名を記憶 ⭐⭐
Cookieを使って、前回入力したユーザー名をフォームに自動入力する機能を作成してください。
- URLパターン:
/remember-me - GETでフォーム表示(Cookieがあれば名前を自動入力)
- POSTで名前をCookieに保存し、挨拶メッセージを表示
- Cookieの有効期限は7日間
模範解答
RememberMeServlet.java
package servlet;
import java.io.IOException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
@WebServlet("/remember-me")
public class RememberMeServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// Cookieから前回の名前を取得
String savedName = "";
Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (Cookie cookie : cookies) {
if ("rememberedName".equals(cookie.getName())) {
savedName = URLDecoder.decode(cookie.getValue(), StandardCharsets.UTF_8);
}
}
}
request.setAttribute("savedName", savedName);
request.getRequestDispatcher("/WEB-INF/remember-form.jsp").forward(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
String name = request.getParameter("name");
// Cookieに名前を保存(7日間)※日本語はURLエンコードが必要
Cookie cookie = new Cookie("rememberedName",
URLEncoder.encode(name, StandardCharsets.UTF_8));
cookie.setMaxAge(7 * 24 * 60 * 60);
cookie.setPath("/");
response.addCookie(cookie);
request.setAttribute("name", name);
request.getRequestDispatcher("/WEB-INF/remember-result.jsp").forward(request, response);
}
}
WEB-INF/remember-form.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<!DOCTYPE html>
<html>
<head><title>名前を記憶</title></head>
<body>
<h1>ログインフォーム</h1>
<% String savedName = (String) request.getAttribute("savedName"); %>
<% if (savedName != null && !savedName.isEmpty()) { %>
<p>前回のお名前を記憶しています。</p>
<% } %>
<form action="<%= request.getContextPath() %>/remember-me" method="post">
<label>名前:</label>
<input type="text" name="name" value="<%= savedName != null ? savedName : "" %>" required />
<button type="submit">送信</button>
</form>
</body>
</html>
WEB-INF/remember-result.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<!DOCTYPE html>
<html>
<head><title>結果</title></head>
<body>
<h1>こんにちは!</h1>
<p>ようこそ、<strong><%= request.getAttribute("name") %></strong> さん!</p>
<p>お名前をCookieに保存しました(7日間有効)。</p>
<p><a href="<%= request.getContextPath() %>/remember-me">フォームに戻る</a></p>
</body>
</html>
問題3:簡易ショッピングカート ⭐⭐
セッションを使った簡易ショッピングカートを作成してください。
- 商品一覧画面:3つ以上の商品を表示し、「カートに追加」ボタンを設置
- カート画面:カートの中身(商品名の一覧)と合計金額を表示
- カートをクリアするボタンを設置
- セッションで
List<String>を管理
模範解答
CartServlet.java
package servlet;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
@WebServlet("/cart")
public class CartServlet extends HttpServlet {
// 商品マスタ(実際にはDBから取得する)
private static final Map<String, Integer> PRODUCTS = new LinkedHashMap<>();
static {
PRODUCTS.put("Javaの教科書", 2800);
PRODUCTS.put("サーブレット入門", 3200);
PRODUCTS.put("データベース実践", 2500);
PRODUCTS.put("Webデザイン基礎", 1800);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String action = request.getParameter("action");
HttpSession session = request.getSession();
@SuppressWarnings("unchecked")
List<String> cart = (List<String>) session.getAttribute("cart");
if (cart == null) {
cart = new ArrayList<>();
session.setAttribute("cart", cart);
}
if ("clear".equals(action)) {
cart.clear();
session.setAttribute("cart", cart);
response.sendRedirect(request.getContextPath() + "/cart");
return;
}
// 合計金額の計算
int total = 0;
for (String item : cart) {
total += PRODUCTS.getOrDefault(item, 0);
}
request.setAttribute("products", PRODUCTS);
request.setAttribute("cart", cart);
request.setAttribute("total", total);
request.getRequestDispatcher("/WEB-INF/cart.jsp").forward(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
String product = request.getParameter("product");
HttpSession session = request.getSession();
@SuppressWarnings("unchecked")
List<String> cart = (List<String>) session.getAttribute("cart");
if (cart == null) {
cart = new ArrayList<>();
}
if (product != null && PRODUCTS.containsKey(product)) {
cart.add(product);
}
session.setAttribute("cart", cart);
response.sendRedirect(request.getContextPath() + "/cart");
}
}
WEB-INF/cart.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<%@ page import="java.util.List, java.util.Map" %>
<!DOCTYPE html>
<html>
<head><title>ショッピングカート</title></head>
<body>
<h1>商品一覧</h1>
<%
@SuppressWarnings("unchecked")
Map<String, Integer> products = (Map<String, Integer>) request.getAttribute("products");
%>
<table border="1">
<tr><th>商品名</th><th>価格</th><th>操作</th></tr>
<% for (Map.Entry<String, Integer> entry : products.entrySet()) { %>
<tr>
<td><%= entry.getKey() %></td>
<td><%= String.format("%,d", entry.getValue()) %> 円</td>
<td>
<form action="<%= request.getContextPath() %>/cart" method="post" style="margin:0;">
<input type="hidden" name="product" value="<%= entry.getKey() %>" />
<button type="submit">カートに追加</button>
</form>
</td>
</tr>
<% } %>
</table>
<h2>カートの中身</h2>
<%
@SuppressWarnings("unchecked")
List<String> cart = (List<String>) request.getAttribute("cart");
int total = (Integer) request.getAttribute("total");
%>
<% if (cart.isEmpty()) { %>
<p>カートは空です。</p>
<% } else { %>
<ul>
<% for (String item : cart) { %>
<li><%= item %></li>
<% } %>
</ul>
<p><strong>合計: <%= String.format("%,d", total) %> 円</strong>(<%= cart.size() %> 点)</p>
<a href="<%= request.getContextPath() %>/cart?action=clear">カートをクリア</a>
<% } %>
</body>
</html>
まとめ
| 学んだこと | キーワード |
|---|---|
| ステートレス | HTTPは状態を持たない、セッション管理が必要 |
| HttpSession |
getSession()、setAttribute()、getAttribute()
|
| セッションの制御 |
invalidate()(無効化)、setMaxInactiveInterval()(タイムアウト) |
| Cookie |
new Cookie()、addCookie()、getCookies()
|
| セッション vs Cookie | サーバー側保存 vs ブラウザ側保存 |
| ログイン機能 | セッションでログイン状態を管理、ログアウトでinvalidate()
|
次回は MVCパターン(Servlet + JSP) を学びます!
シリーズ一覧:Servlet/JSP入門
- 環境構築とはじめてのServlet
- HTTPリクエストとレスポンス
- JSPの基礎
- フォーム処理(GET/POST)
- 👉 セッション管理とCookie(本記事)
- MVCパターン(Servlet + JSP)
- JDBC連携(データベース操作)
- EL式とJSTL
- フィルターとリスナー
- 総合演習:掲示板アプリを作ろう
著者: @kotaro_ai_lab
AI駆動開発やテック情報を毎日発信しています。フォローお気軽にどうぞ!