はじめに
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>、action、method、各種<input>
|
| GETフォーム処理 | URLクエリストリング、検索向き |
| POSTフォーム処理 | リクエストボディ、データ登録向き |
| doGet / doPost | HTTPメソッドに対応するServletメソッド |
| forward |
RequestDispatcher、サーバー内部転送、requestデータ引き継ぎ |
| redirect |
sendRedirect、URL変更、二重送信防止(PRG) |
| バリデーション | 入力値の検証、エラーメッセージ表示 |
次回は セッション管理とCookie を学びます!
シリーズ一覧:Servlet/JSP入門
- 環境構築とはじめてのServlet
- HTTPリクエストとレスポンス
- JSPの基礎
- 👉 フォーム処理(GET/POST)(本記事)
- セッション管理とCookie
- MVCパターン(Servlet + JSP)
- JDBC連携(データベース操作)
- EL式とJSTL
- フィルターとリスナー
- 総合演習:掲示板アプリを作ろう
著者: @kotaro_ai_lab
AI駆動開発やテック情報を毎日発信しています。フォローお気軽にどうぞ!