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入門④ フォーム処理(GET/POST)

0
Posted at

はじめに

Servlet/JSP入門の第4回は フォーム処理(GET/POST) です。

Webアプリケーションではユーザーからの入力を受け取る場面が頻繁にあります。HTMLフォームで送信されたデータをServletで受け取り、処理結果をJSPで表示するという基本パターンを学びましょう。

第4回で学ぶこと

  • HTMLフォームの基本
  • GETリクエストでのフォームデータ処理
  • POSTリクエストでのフォームデータ処理
  • doGetとdoPostの違い
  • フォーム → Servlet → JSP パターン(forward)
  • forwardとredirectの違い
  • 入力値の検証(バリデーション)

1. HTMLフォームの基本

フォームの構造

<form action="送信先URL" method="HTTPメソッド">
    <input type="種類" name="パラメータ名" />
    <button type="submit">送信</button>
</form>
属性 説明
action フォームの送信先URL /WebStudy/register
method HTTPメソッド(GET/POST) get または post

主なinput要素

type属性 説明
text テキスト入力 <input type="text" name="name" />
password パスワード入力 <input type="password" name="pass" />
number 数値入力 <input type="number" name="age" />
email メールアドレス <input type="email" name="email" />
radio ラジオボタン <input type="radio" name="gender" value="male" />
checkbox チェックボックス <input type="checkbox" name="hobby" value="reading" />
hidden 隠しフィールド <input type="hidden" name="id" value="1" />
submit 送信ボタン <input type="submit" value="送信" />

その他のフォーム要素:

<!-- セレクトボックス -->
<select name="department">
    <option value="dev">開発部</option>
    <option value="sales">営業部</option>
</select>

<!-- テキストエリア -->
<textarea name="comment" rows="5" cols="40"></textarea>

2. GETリクエストでのフォーム処理

GETメソッドでは、フォームのデータがURLのクエリストリングとして送信されます。

検索フォームの例

search.jsp(フォーム画面)

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<!DOCTYPE html>
<html>
<head><title>検索</title></head>
<body>
    <h1>商品検索</h1>
    <form action="<%= request.getContextPath() %>/search" method="get">
        <label>キーワード:</label>
        <input type="text" name="keyword" placeholder="検索キーワード" />
        <button type="submit">検索</button>
    </form>
</body>
</html>

SearchServlet.java(処理)

package servlet;

import java.io.IOException;
import java.io.PrintWriter;

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

@WebServlet("/search")
public class SearchServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        request.setCharacterEncoding("UTF-8");
        response.setContentType("text/html; charset=UTF-8");

        String keyword = request.getParameter("keyword");
        PrintWriter out = response.getWriter();

        out.println("<!DOCTYPE html>");
        out.println("<html><body>");
        out.println("<h1>検索結果</h1>");

        if (keyword != null && !keyword.isEmpty()) {
            out.println("<p>「" + keyword + "」の検索結果を表示します。</p>");
        } else {
            out.println("<p>キーワードが入力されていません。</p>");
        }

        out.println("<p><a href='search.jsp'>検索画面に戻る</a></p>");
        out.println("</body></html>");
    }
}

送信すると、URLは http://localhost:8080/WebStudy/search?keyword=Java のようになります。


3. POSTリクエストでのフォーム処理

POSTメソッドでは、データがリクエストボディに含まれて送信されます。ログインや会員登録など、機密情報を含むデータの送信に使います。

ユーザー登録フォームの例

register.jsp(フォーム画面)

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<!DOCTYPE html>
<html>
<head><title>ユーザー登録</title></head>
<body>
    <h1>ユーザー登録</h1>
    <form action="<%= request.getContextPath() %>/register" method="post">
        <table>
            <tr>
                <td><label>名前:</label></td>
                <td><input type="text" name="name" required /></td>
            </tr>
            <tr>
                <td><label>メール:</label></td>
                <td><input type="email" name="email" required /></td>
            </tr>
            <tr>
                <td><label>パスワード:</label></td>
                <td><input type="password" name="password" required /></td>
            </tr>
            <tr>
                <td><label>年齢:</label></td>
                <td><input type="number" name="age" min="0" max="150" /></td>
            </tr>
            <tr>
                <td><label>部署:</label></td>
                <td>
                    <select name="department">
                        <option value="dev">開発部</option>
                        <option value="sales">営業部</option>
                        <option value="hr">人事部</option>
                    </select>
                </td>
            </tr>
            <tr>
                <td></td>
                <td><button type="submit">登録</button></td>
            </tr>
        </table>
    </form>
</body>
</html>

RegisterServlet.java(処理)

package servlet;

import java.io.IOException;
import java.io.PrintWriter;

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

@WebServlet("/register")
public class RegisterServlet extends HttpServlet {

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        request.setCharacterEncoding("UTF-8");
        response.setContentType("text/html; charset=UTF-8");

        // フォームデータの取得
        String name = request.getParameter("name");
        String email = request.getParameter("email");
        String password = request.getParameter("password");
        String ageStr = request.getParameter("age");
        String department = request.getParameter("department");

        PrintWriter out = response.getWriter();
        out.println("<!DOCTYPE html>");
        out.println("<html><body>");
        out.println("<h1>登録完了</h1>");
        out.println("<table border='1'>");
        out.println("<tr><th>項目</th><th>入力値</th></tr>");
        out.println("<tr><td>名前</td><td>" + name + "</td></tr>");
        out.println("<tr><td>メール</td><td>" + email + "</td></tr>");
        out.println("<tr><td>パスワード</td><td>****</td></tr>");
        out.println("<tr><td>年齢</td><td>" + ageStr + "</td></tr>");
        out.println("<tr><td>部署</td><td>" + department + "</td></tr>");
        out.println("</table>");
        out.println("<p><a href='register.jsp'>登録画面に戻る</a></p>");
        out.println("</body></html>");
    }
}

4. doGet と doPost の違い

項目 doGet doPost
呼ばれるとき GETリクエスト時 POSTリクエスト時
データの場所 URLクエリストリング リクエストボディ
ブラウザの戻る/更新 安全に再送信可能 再送信の警告が出る
ブックマーク パラメータごとブックマーク可能 不可
主な用途 データの取得・検索 データの登録・更新・削除

両方に対応するServlet

GETでフォームを表示し、POSTでデータを処理するパターンはよく使います。

@WebServlet("/contact")
public class ContactServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // GETリクエスト → フォーム画面を表示
        request.getRequestDispatcher("/WEB-INF/contact.jsp").forward(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // POSTリクエスト → フォームデータを処理
        request.setCharacterEncoding("UTF-8");
        String name = request.getParameter("name");
        String message = request.getParameter("message");

        request.setAttribute("name", name);
        request.setAttribute("message", message);
        request.getRequestDispatcher("/WEB-INF/contact-result.jsp").forward(request, response);
    }
}

5. フォーム → Servlet → JSP パターン(forward)

実際の開発では、Servletで処理を行い、結果をJSPで表示するパターンが基本です。

┌──────────┐     POST      ┌───────────┐    forward    ┌──────────┐
│  フォーム  │  ──────────→  │  Servlet   │  ────────→  │   JSP    │
│  (JSP)    │              │  (処理)     │              │  (表示)   │
└──────────┘              └───────────┘              └──────────┘

forwardの書き方

// Servletからデータをセット
request.setAttribute("キー名", );

// JSPにフォワード
request.getRequestDispatcher("/WEB-INF/result.jsp").forward(request, response);

完全な例:BMI計算

BmiServlet.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;

@WebServlet("/bmi")
public class BmiServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // フォーム画面を表示
        request.getRequestDispatcher("/WEB-INF/bmi-form.jsp").forward(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        request.setCharacterEncoding("UTF-8");

        String heightStr = request.getParameter("height");
        String weightStr = request.getParameter("weight");

        double height = Double.parseDouble(heightStr) / 100.0; // cmをmに変換
        double weight = Double.parseDouble(weightStr);
        double bmi = weight / (height * height);

        // 判定
        String category;
        if (bmi < 18.5) {
            category = "低体重";
        } else if (bmi < 25.0) {
            category = "普通体重";
        } else if (bmi < 30.0) {
            category = "肥満(1度)";
        } else {
            category = "肥満(2度以上)";
        }

        // 結果をリクエストスコープにセット
        request.setAttribute("bmi", String.format("%.1f", bmi));
        request.setAttribute("category", category);
        request.setAttribute("height", heightStr);
        request.setAttribute("weight", weightStr);

        // JSPにフォワード
        request.getRequestDispatcher("/WEB-INF/bmi-result.jsp").forward(request, response);
    }
}

WEB-INF/bmi-form.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<!DOCTYPE html>
<html>
<head><title>BMI計算</title></head>
<body>
    <h1>BMI計算</h1>
    <form action="<%= request.getContextPath() %>/bmi" method="post">
        <p>
            <label>身長 (cm):</label>
            <input type="number" name="height" step="0.1" required />
        </p>
        <p>
            <label>体重 (kg):</label>
            <input type="number" name="weight" step="0.1" required />
        </p>
        <button type="submit">計算する</button>
    </form>
</body>
</html>

WEB-INF/bmi-result.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<!DOCTYPE html>
<html>
<head><title>BMI計算結果</title></head>
<body>
    <h1>BMI計算結果</h1>
    <table border="1">
        <tr><th>項目</th><th></th></tr>
        <tr><td>身長</td><td><%= request.getAttribute("height") %> cm</td></tr>
        <tr><td>体重</td><td><%= request.getAttribute("weight") %> kg</td></tr>
        <tr><td>BMI</td><td><%= request.getAttribute("bmi") %></td></tr>
        <tr><td>判定</td><td><%= request.getAttribute("category") %></td></tr>
    </table>
    <p><a href="<%= request.getContextPath() %>/bmi">もう一度計算する</a></p>
</body>
</html>

ポイント: JSPファイルを WEB-INF フォルダの中に置くと、ブラウザから直接アクセスできなくなります。必ずServletを経由してforwardでアクセスすることになり、セキュリティが向上します。


6. forward と redirect の違い

forward(転送)

request.getRequestDispatcher("/WEB-INF/result.jsp").forward(request, response);
  • サーバー内部 で処理を別のリソースに転送する
  • URLは 変わらない(ブラウザは転送を知らない)
  • request のデータを引き継げる

redirect(リダイレクト)

response.sendRedirect(request.getContextPath() + "/complete");
  • ブラウザに 別のURLへアクセスし直す よう指示する
  • URLが 変わる
  • request のデータは引き継がれない(新しいリクエスト)

動作の違い

【forward】
ブラウザ → リクエスト → Servlet ──(内部転送)──→ JSP → レスポンス → ブラウザ
                                                        URLは変わらない

【redirect】
ブラウザ → リクエスト → Servlet → 302レスポンス → ブラウザ
ブラウザ → 新しいリクエスト → 別のServlet/JSP → レスポンス → ブラウザ
                                                        URLが変わる

比較表

項目 forward redirect
URLの変化 変わらない 変わる
リクエスト回数 1回 2回
requestの引き継ぎ 可能 不可
速度 速い やや遅い
用途 処理結果の表示 画面遷移(登録完了後など)

使い分けの基準

データ処理後の表示 → forward
  例:検索結果の表示、入力確認画面

画面遷移(別の処理に移る)→ redirect
  例:ログイン後のトップページ、登録完了画面

PRG(Post-Redirect-Get)パターン: POST処理の後にredirectすると、ブラウザの「戻る」ボタンで再送信される問題を防げます。

@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {

    // データの登録処理
    // ...

    // 登録完了後はリダイレクト(二重送信防止)
    response.sendRedirect(request.getContextPath() + "/complete");
}

7. 入力値の検証(バリデーション)

ユーザーからの入力は必ず検証しましょう。

バリデーションの基本

@WebServlet("/validate-demo")
public class ValidationServlet extends HttpServlet {

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        request.setCharacterEncoding("UTF-8");

        String name = request.getParameter("name");
        String ageStr = request.getParameter("age");
        String email = request.getParameter("email");

        // エラーメッセージを格納するリスト
        java.util.List<String> errors = new java.util.ArrayList<>();

        // 名前の検証
        if (name == null || name.trim().isEmpty()) {
            errors.add("名前を入力してください。");
        }

        // 年齢の検証
        int age = 0;
        if (ageStr == null || ageStr.trim().isEmpty()) {
            errors.add("年齢を入力してください。");
        } else {
            try {
                age = Integer.parseInt(ageStr);
                if (age < 0 || age > 150) {
                    errors.add("年齢は0~150の範囲で入力してください。");
                }
            } catch (NumberFormatException e) {
                errors.add("年齢は数値で入力してください。");
            }
        }

        // メールの検証
        if (email == null || !email.contains("@")) {
            errors.add("正しいメールアドレスを入力してください。");
        }

        if (errors.isEmpty()) {
            // バリデーション成功 → 結果画面へ
            request.setAttribute("name", name);
            request.setAttribute("age", age);
            request.setAttribute("email", email);
            request.getRequestDispatcher("/WEB-INF/success.jsp").forward(request, response);
        } else {
            // バリデーション失敗 → フォームに戻す
            request.setAttribute("errors", errors);
            request.setAttribute("name", name);
            request.setAttribute("age", ageStr);
            request.setAttribute("email", email);
            request.getRequestDispatcher("/WEB-INF/form.jsp").forward(request, response);
        }
    }
}

エラーメッセージを表示するJSP

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<%@ page import="java.util.List" %>
<!DOCTYPE html>
<html>
<head><title>入力フォーム</title></head>
<body>
    <h1>ユーザー登録</h1>

    <%-- エラーメッセージの表示 --%>
    <%
        List<String> errors = (List<String>) request.getAttribute("errors");
        if (errors != null && !errors.isEmpty()) {
    %>
    <div style="color: red; border: 1px solid red; padding: 10px; margin-bottom: 10px;">
        <strong>入力エラー:</strong>
        <ul>
        <% for (String error : errors) { %>
            <li><%= error %></li>
        <% } %>
        </ul>
    </div>
    <% } %>

    <form action="<%= request.getContextPath() %>/validate-demo" method="post">
        <p>
            <label>名前:</label>
            <input type="text" name="name"
                   value="<%= request.getAttribute("name") != null ? request.getAttribute("name") : "" %>" />
        </p>
        <p>
            <label>年齢:</label>
            <input type="text" name="age"
                   value="<%= request.getAttribute("age") != null ? request.getAttribute("age") : "" %>" />
        </p>
        <p>
            <label>メール:</label>
            <input type="text" name="email"
                   value="<%= request.getAttribute("email") != null ? request.getAttribute("email") : "" %>" />
        </p>
        <button type="submit">登録</button>
    </form>
</body>
</html>

ポイント: バリデーションエラー時に、入力済みの値をフォームに再表示することで、ユーザーが最初から入力し直す手間を省けます。


練習問題

問題1:アンケートフォーム ⭐

好きなプログラミング言語を選択するアンケートフォームを作成してください。

  • フォーム画面をJSP、処理をServletで実装
  • ラジオボタンで言語を選択(Java, Python, JavaScript, その他)
  • 送信後、選んだ言語を表示
模範解答

survey.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<!DOCTYPE html>
<html>
<head><title>アンケート</title></head>
<body>
    <h1>好きなプログラミング言語アンケート</h1>
    <form action="<%= request.getContextPath() %>/survey" method="post">
        <p>好きな言語を選んでください:</p>
        <label><input type="radio" name="language" value="Java" /> Java</label><br />
        <label><input type="radio" name="language" value="Python" /> Python</label><br />
        <label><input type="radio" name="language" value="JavaScript" /> JavaScript</label><br />
        <label><input type="radio" name="language" value="その他" /> その他</label><br />
        <br />
        <button type="submit">送信</button>
    </form>
</body>
</html>

SurveyServlet.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;

@WebServlet("/survey")
public class SurveyServlet extends HttpServlet {

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        request.setCharacterEncoding("UTF-8");

        String language = request.getParameter("language");

        if (language == null) {
            language = "未選択";
        }

        request.setAttribute("language", language);
        request.getRequestDispatcher("/WEB-INF/survey-result.jsp").forward(request, response);
    }
}

WEB-INF/survey-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("language") %></strong></p>
    <p><a href="survey.jsp">もう一度回答する</a></p>
</body>
</html>

問題2:温度変換アプリ ⭐⭐

摂氏(°C)と華氏(°F)を相互変換するアプリを作成してください。

  • GETでフォーム表示、POSTで変換処理
  • 変換方向をセレクトボックスで選択(摂氏→華氏、華氏→摂氏)
  • 計算式:°F = °C × 9/5 + 32 / °C = (°F - 32) × 5/9
  • forwardで結果をJSPに表示
模範解答

TempConvertServlet.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;

@WebServlet("/temp-convert")
public class TempConvertServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        request.getRequestDispatcher("/WEB-INF/temp-form.jsp").forward(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        request.setCharacterEncoding("UTF-8");

        String tempStr = request.getParameter("temperature");
        String direction = request.getParameter("direction");

        try {
            double temp = Double.parseDouble(tempStr);
            double result;
            String fromUnit;
            String toUnit;

            if ("c_to_f".equals(direction)) {
                result = temp * 9.0 / 5.0 + 32;
                fromUnit = "°C";
                toUnit = "°F";
            } else {
                result = (temp - 32) * 5.0 / 9.0;
                fromUnit = "°F";
                toUnit = "°C";
            }

            request.setAttribute("inputTemp", String.format("%.1f", temp));
            request.setAttribute("resultTemp", String.format("%.1f", result));
            request.setAttribute("fromUnit", fromUnit);
            request.setAttribute("toUnit", toUnit);
            request.getRequestDispatcher("/WEB-INF/temp-result.jsp").forward(request, response);

        } catch (NumberFormatException e) {
            request.setAttribute("error", "数値を正しく入力してください。");
            request.getRequestDispatcher("/WEB-INF/temp-form.jsp").forward(request, response);
        }
    }
}

WEB-INF/temp-form.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() %>/temp-convert" method="post">
        <p>
            <label>温度:</label>
            <input type="text" name="temperature" required />
        </p>
        <p>
            <label>変換方向:</label>
            <select name="direction">
                <option value="c_to_f">摂氏(°C) → 華氏(°F)</option>
                <option value="f_to_c">華氏(°F) → 摂氏(°C)</option>
            </select>
        </p>
        <button type="submit">変換</button>
    </form>
</body>
</html>

WEB-INF/temp-result.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<!DOCTYPE html>
<html>
<head><title>変換結果</title></head>
<body>
    <h1>変換結果</h1>
    <table border="1">
        <tr><th>入力値</th><td><%= request.getAttribute("inputTemp") %> <%= request.getAttribute("fromUnit") %></td></tr>
        <tr><th>変換結果</th><td><%= request.getAttribute("resultTemp") %> <%= request.getAttribute("toUnit") %></td></tr>
    </table>
    <p><a href="<%= request.getContextPath() %>/temp-convert">もう一度変換する</a></p>
</body>
</html>

問題3:会員登録フォーム(バリデーション付き) ⭐⭐

以下の要件で会員登録フォームを作成してください。

  • 入力項目:名前(必須)、メールアドレス(必須、@を含む)、年齢(必須、1~120)、性別(ラジオボタン)
  • バリデーションエラー時はフォームに戻り、エラーメッセージと入力済みの値を表示
  • バリデーション成功時は確認画面を表示
模範解答

MemberServlet.java

package servlet;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

@WebServlet("/member")
public class MemberServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        request.getRequestDispatcher("/WEB-INF/member-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");
        String email = request.getParameter("email");
        String ageStr = request.getParameter("age");
        String gender = request.getParameter("gender");

        List<String> errors = new ArrayList<>();

        // 名前の検証
        if (name == null || name.trim().isEmpty()) {
            errors.add("名前を入力してください。");
        }

        // メールの検証
        if (email == null || email.trim().isEmpty()) {
            errors.add("メールアドレスを入力してください。");
        } else if (!email.contains("@")) {
            errors.add("正しいメールアドレスを入力してください。");
        }

        // 年齢の検証
        int age = 0;
        if (ageStr == null || ageStr.trim().isEmpty()) {
            errors.add("年齢を入力してください。");
        } else {
            try {
                age = Integer.parseInt(ageStr);
                if (age < 1 || age > 120) {
                    errors.add("年齢は1~120の範囲で入力してください。");
                }
            } catch (NumberFormatException e) {
                errors.add("年齢は数値で入力してください。");
            }
        }

        // 性別の検証
        if (gender == null) {
            errors.add("性別を選択してください。");
        }

        // 入力値を保持
        request.setAttribute("name", name);
        request.setAttribute("email", email);
        request.setAttribute("age", ageStr);
        request.setAttribute("gender", gender);

        if (errors.isEmpty()) {
            request.getRequestDispatcher("/WEB-INF/member-confirm.jsp").forward(request, response);
        } else {
            request.setAttribute("errors", errors);
            request.getRequestDispatcher("/WEB-INF/member-form.jsp").forward(request, response);
        }
    }
}

WEB-INF/member-form.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<%@ page import="java.util.List" %>
<!DOCTYPE html>
<html>
<head><title>会員登録</title></head>
<body>
    <h1>会員登録</h1>

    <%
        List<String> errors = (List<String>) request.getAttribute("errors");
        if (errors != null && !errors.isEmpty()) {
    %>
    <div style="color: red; border: 1px solid red; padding: 10px;">
        <ul>
        <% for (String error : errors) { %>
            <li><%= error %></li>
        <% } %>
        </ul>
    </div>
    <% } %>

    <%
        String name = request.getAttribute("name") != null ? (String) request.getAttribute("name") : "";
        String email = request.getAttribute("email") != null ? (String) request.getAttribute("email") : "";
        String age = request.getAttribute("age") != null ? (String) request.getAttribute("age") : "";
        String gender = request.getAttribute("gender") != null ? (String) request.getAttribute("gender") : "";
    %>

    <form action="<%= request.getContextPath() %>/member" method="post">
        <table>
            <tr>
                <td>名前 <span style="color:red;">*</span></td>
                <td><input type="text" name="name" value="<%= name %>" /></td>
            </tr>
            <tr>
                <td>メール <span style="color:red;">*</span></td>
                <td><input type="text" name="email" value="<%= email %>" /></td>
            </tr>
            <tr>
                <td>年齢 <span style="color:red;">*</span></td>
                <td><input type="text" name="age" value="<%= age %>" /></td>
            </tr>
            <tr>
                <td>性別 <span style="color:red;">*</span></td>
                <td>
                    <label><input type="radio" name="gender" value="male" <%= "male".equals(gender) ? "checked" : "" %> /> 男性</label>
                    <label><input type="radio" name="gender" value="female" <%= "female".equals(gender) ? "checked" : "" %> /> 女性</label>
                    <label><input type="radio" name="gender" value="other" <%= "other".equals(gender) ? "checked" : "" %> /> その他</label>
                </td>
            </tr>
            <tr>
                <td></td>
                <td><button type="submit">登録</button></td>
            </tr>
        </table>
    </form>
</body>
</html>

WEB-INF/member-confirm.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<!DOCTYPE html>
<html>
<head><title>登録確認</title></head>
<body>
    <h1>登録内容の確認</h1>
    <%
        String genderLabel;
        String gender = (String) request.getAttribute("gender");
        if ("male".equals(gender)) {
            genderLabel = "男性";
        } else if ("female".equals(gender)) {
            genderLabel = "女性";
        } else {
            genderLabel = "その他";
        }
    %>
    <table border="1">
        <tr><th>項目</th><th>入力内容</th></tr>
        <tr><td>名前</td><td><%= request.getAttribute("name") %></td></tr>
        <tr><td>メール</td><td><%= request.getAttribute("email") %></td></tr>
        <tr><td>年齢</td><td><%= request.getAttribute("age") %></td></tr>
        <tr><td>性別</td><td><%= genderLabel %></td></tr>
    </table>
    <p>登録が完了しました。</p>
    <p><a href="<%= request.getContextPath() %>/member">新規登録画面へ</a></p>
</body>
</html>

まとめ

学んだこと キーワード
HTMLフォーム <form>actionmethod、各種<input>
GETフォーム処理 URLクエリストリング、検索向き
POSTフォーム処理 リクエストボディ、データ登録向き
doGet / doPost HTTPメソッドに対応するServletメソッド
forward RequestDispatcher、サーバー内部転送、requestデータ引き継ぎ
redirect sendRedirect、URL変更、二重送信防止(PRG)
バリデーション 入力値の検証、エラーメッセージ表示

次回は セッション管理とCookie を学びます!


シリーズ一覧: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?