0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Java研修】Servlet/JSP入門⑤ セッション管理とCookie

0
Posted at

はじめに

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.xmlsession-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入門

  1. 環境構築とはじめてのServlet
  2. HTTPリクエストとレスポンス
  3. JSPの基礎
  4. フォーム処理(GET/POST)
  5. 👉 セッション管理とCookie(本記事)
  6. MVCパターン(Servlet + JSP)
  7. JDBC連携(データベース操作)
  8. EL式とJSTL
  9. フィルターとリスナー
  10. 総合演習:掲示板アプリを作ろう

著者: @kotaro_ai_lab
AI駆動開発やテック情報を毎日発信しています。フォローお気軽にどうぞ!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?