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?

ユーザー登録機能の実装手順

前提: 「JSP/Servlet 環境設定手順書」のセクション3まで完了していること


全体の流れ

ステップ 学ぶこと 作成・変更するファイル
1 サーブレットからINSERTする方法 UserDao.java, InsertServlet.java, web.xml
2 フォームの値をサーブレットで受け取る方法 form.jsp, FormServlet.java, web.xml
3 フォーム入力をDBに登録する方法 FormServlet.java を修正
4 成功・失敗で画面を切り替える方法 success.jsp, FormServlet.java を修正

全体像: 各ステップで何が増えるか


ステップ 1: サーブレットからデータを追加する

目的

URLにアクセスするだけで、サーブレットがデータベースに1件INSERTする仕組みを作る。
まだフォームは使わず、Javaコードからデータを登録する流れを理解する。

1-1. UserDao に insert メソッドを追加

UserDao.java を開き、getById() メソッドのに以下のメソッドを追加する。

/**
 * ユーザーを1件データベースに登録する。
 *
 * getById() との違い:
 *   getById() → SELECT(読み取り)→ executeQuery()  → ResultSet が返る
 *   insert()  → INSERT(書き込み)→ executeUpdate() → 処理件数(int) が返る
 *
 * @param user 登録するユーザー情報(email, name, password を設定済みであること)
 * @return 登録成功なら true、失敗(email重複など)なら false
 */
public boolean insert(User user) {
    try {
        Class.forName("com.mysql.cj.jdbc.Driver");
        Connection conn = DriverManager.getConnection(URL, USER, PASS);

        // INSERT文を準備(? はプレースホルダー)
        // user_id は AUTO_INCREMENT なので指定しない → DBが自動採番
        PreparedStatement ps = conn.prepareStatement(
                "INSERT INTO users (email, name, password) VALUES (?, ?, ?)");

        // ? に値をセット(1番目 = email, 2番目 = name, 3番目 = password)
        ps.setString(1, user.getEmail());
        ps.setString(2, user.getName());
        ps.setString(3, user.getPassword());

        // INSERT/UPDATE/DELETE は executeUpdate() を使う(executeQuery() は SELECT 用)
        // 戻り値は「何件処理したか」(INSERT 1件なら 1 が返る)
        int count = ps.executeUpdate();
        return count > 0;
    } catch (SQLException | ClassNotFoundException e) {
        e.printStackTrace();
        return false;
    }
}

getById() と insert() の比較:

getById()(SELECT) insert()(INSERT)
SQL実行メソッド executeQuery() executeUpdate()
戻り値 ResultSet(検索結果の行) int(処理した件数)
用途 データを読む データを書く

1-2. InsertServlet の作成

controller パッケージに InsertServlet.java を新規作成する。

プロジェクトを右クリック → 新規 → その他 → Web → サーブレット
パッケージ: controller、クラス名: InsertServlet

生成されたコードを以下の内容にすべて置き換える:

package controller;

import java.io.IOException;

import jakarta.servlet.RequestDispatcher;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import dao.UserDao;
import dto.User;

/**
 * データベースにユーザーを1件INSERTするサーブレット。
 *
 * ステップ1の学習用: フォームを使わず、Javaコードから直接データを登録する。
 * ブラウザで /insert にアクセスするだけで INSERT が実行される。
 *
 * URLマッピング: /insert(web.xmlで設定)
 */
public class InsertServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    /**
     * GETリクエストの処理。/insert にアクセスすると呼ばれる。
     *
     * 処理の流れ:
     *   Userオブジェクト作成 → UserDao.insert() でDB登録 → hello.jsp で結果表示
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        // 登録するデータをJavaコードで直接作成(ステップ2以降ではフォームから受け取る)
        User user = new User();
        user.setEmail("yamada@example.com");
        user.setName("山田花子");
        user.setPassword("pass123");

        // DAOのinsertメソッドでデータベースに登録
        // 成功なら true、失敗(email重複など)なら false が返る
        UserDao userDao = new UserDao();
        boolean result = userDao.insert(user);

        // 結果をEclipseのコンソールに表示(開発時のデバッグ用)
        if (result) {
            System.out.println("登録成功: " + user.getName());
        } else {
            System.out.println("登録失敗");
        }

        // hello.jsp にフォワードして画面を表示
        User savedUser = userDao.getById(2);
        request.setAttribute("user", savedUser);
        RequestDispatcher dispatcher = request.getRequestDispatcher("/WEB-INF/hello.jsp");
        dispatcher.forward(request, response);
    }
}

1-3. web.xml にマッピングを追加

web.xml を開き、既存の </servlet-mapping> の下に以下を追加する。

web.xml は「どのURLにアクセスしたら、どのサーブレットが動くか」を定義する設定ファイル。

<!-- サーブレットの登録: クラス名とサーブレット名を紐づける -->
<servlet>
    <servlet-name>InsertServlet</servlet-name>
    <servlet-class>controller.InsertServlet</servlet-class>
</servlet>
<!-- URLマッピング: /insert にアクセスしたら InsertServlet を実行 -->
<servlet-mapping>
    <servlet-name>InsertServlet</servlet-name>
    <url-pattern>/insert</url-pattern>
</servlet-mapping>

web.xml の仕組み:

ブラウザで /insert にアクセス
    ↓
web.xml: /insert → InsertServlet(servlet-mapping で対応づけ)
    ↓
controller.InsertServlet.doGet() が実行される

1-4. 動作確認

  1. プロジェクトを右クリック → 実行 → サーバーで実行
  2. ブラウザで http://localhost:8080/Hello/insert にアクセス
  3. Eclipseのコンソールに「登録成功: 山田花子」と表示されることを確認
  4. Workbench で SELECT * FROM users; を実行し、山田花子が追加されていることを確認

注意: アクセスするたびにINSERTが実行される。ただし email に UNIQUE 制約があるため、2回目以降はエラーになる。Workbench で DELETE FROM users WHERE email = 'yamada@example.com'; を実行すれば再度試せる。


ステップ 2: Webフォームを作り、入力値をサーブレットで受け取る

目的

HTMLフォームにユーザーが入力した値を、サーブレット側で受け取って画面に表示する。
まだDBには保存せず、フォーム → サーブレット → JSP の流れを理解する。

2-1. form.jsp の作成

WEB-INF フォルダを右クリック → 新規 → その他 → Web → JSPファイル →
ファイル名: form.jsp

内容を以下にする:

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

    <%--
      フォームの仕組み:
        action  = 送信先のURL。ボタンを押すとこのURLにデータが送られる
        method  = "post" → サーブレットの doPost() が呼ばれる
                  "get"  → サーブレットの doGet() が呼ばれる(デフォルト)

      ${pageContext.request.contextPath} はアプリのルート(/Hello)を自動取得する。
      これを使うことで、アプリ名が変わっても動作する。
    --%>
    <form action="${pageContext.request.contextPath}/form" method="post">
        <table>
            <tr>
                <td>メールアドレス:</td>
                <%-- name="email" → サーブレット側で request.getParameter("email") に対応 --%>
                <td><input type="email" name="email" required></td>
            </tr>
            <tr>
                <td>名前:</td>
                <%-- name="name" → サーブレット側で request.getParameter("name") に対応 --%>
                <td><input type="text" name="name" required></td>
            </tr>
            <tr>
                <td>パスワード:</td>
                <%-- type="password" で入力値が ●●● で表示される --%>
                <td><input type="password" name="password" required></td>
            </tr>
        </table>
        <br>
        <button type="submit">登録</button>
    </form>
</body>
</html>

フォームとサーブレットの対応関係:

JSP側                              サーブレット側
─────────────────────────────────────────────────────
name="email"          →   request.getParameter("email")
name="name"           →   request.getParameter("name")
name="password"       →   request.getParameter("password")
method="post"         →   doPost() が呼ばれる
action=".../form"     →   web.xml の /form にマッピングされたサーブレット

2-2. FormServlet の作成

controller パッケージに FormServlet.java を新規作成する。

package controller;

import java.io.IOException;

import jakarta.servlet.RequestDispatcher;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

/**
 * ユーザー登録フォームを表示し、送信されたデータを受け取るサーブレット。
 *
 * このサーブレットは2つのHTTPメソッドで異なる処理を行う:
 *   GET  → フォーム画面を表示する(ブラウザでURLにアクセスしたとき)
 *   POST → フォームから送信されたデータを受け取る(「登録」ボタンを押したとき)
 *
 * URLマッピング: /form(web.xmlで設定)
 */
public class FormServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    /**
     * GETリクエスト: フォーム画面を表示する。
     * ブラウザで http://localhost:8080/Hello/form にアクセスすると呼ばれる。
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        RequestDispatcher dispatcher = request.getRequestDispatcher("/WEB-INF/form.jsp");
        dispatcher.forward(request, response);
    }

    /**
     * POSTリクエスト: フォームから送信されたデータを受け取る。
     * form.jsp の「登録」ボタンを押すと呼ばれる。
     *
     * データの受け渡し:
     *   JSPのフォーム → getParameter() で受け取り → setAttribute() でJSPに渡す
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        // 日本語が文字化けしないようにエンコーディングを指定
        request.setCharacterEncoding("UTF-8");

        // フォームの値を受け取る
        // getParameter("email") の "email" は、JSP の <input name="email"> に対応
        String email = request.getParameter("email");
        String name = request.getParameter("name");
        String password = request.getParameter("password");

        // Eclipseのコンソールに表示して確認(開発時のデバッグ用)
        System.out.println("受け取った値:");
        System.out.println("  email: " + email);
        System.out.println("  name: " + name);
        System.out.println("  password: " + password);

        // 受け取った値を「リクエストスコープ」に設定してJSPに渡す
        // setAttribute("email", email) → JSP側で request.getAttribute("email") で取り出せる
        request.setAttribute("email", email);
        request.setAttribute("name", name);
        request.setAttribute("password", password);

        // フォーム画面に戻して入力値を表示する
        RequestDispatcher dispatcher = request.getRequestDispatcher("/WEB-INF/form.jsp");
        dispatcher.forward(request, response);
    }
}

getParameter と getAttribute の違い:

getParameter getAttribute
値の送り元 HTMLフォーム(ブラウザ → サーブレット) setAttribute(サーブレット → JSP)
使う場面 フォーム入力を受け取る サーブレットからJSPにデータを渡す
常に String Object(キャストが必要)

2-3. form.jsp に受け取った値の表示を追加

form.jsp の </form> の下に以下を追加する:

<%
    // サーブレットが setAttribute で渡した値を取り出す
    // 初回アクセス(GET)時は setAttribute されていないので null になる
    String email = (String) request.getAttribute("email");

    // null でない = POST でデータが送られた → 受け取った値を表示
    if (email != null) {
%>
    <hr>
    <h2>受け取った値</h2>
    <ul>
        <%-- <%= ... %> で getAttribute の値をHTMLに出力 --%>
        <li>メールアドレス: <%= request.getAttribute("email") %></li>
        <li>名前: <%= request.getAttribute("name") %></li>
        <li>パスワード: <%= request.getAttribute("password") %></li>
    </ul>
<%
    }
%>

2-4. web.xml にマッピングを追加

<servlet>
    <servlet-name>FormServlet</servlet-name>
    <servlet-class>controller.FormServlet</servlet-class>
</servlet>
<!-- /form へのGET → FormServlet.doGet()(フォーム表示) -->
<!-- /form へのPOST → FormServlet.doPost()(データ受取) -->
<servlet-mapping>
    <servlet-name>FormServlet</servlet-name>
    <url-pattern>/form</url-pattern>
</servlet-mapping>

2-5. 動作確認

  1. サーバーを再起動
  2. http://localhost:8080/Hello/form にアクセス → フォームが表示される
  3. 各項目を入力して「登録」ボタンを押す
  4. 画面に「受け取った値」が表示されることを確認
  5. Eclipseのコンソールにも同じ値が出力されていることを確認

ステップ 3: フォーム入力をデータベースに登録する

目的

ステップ1の「DBに登録する処理」とステップ2の「フォームから値を受け取る処理」を組み合わせる。

3-1. FormServlet の doPost を修正

FormServlet.javadoPost() を以下にすべて置き換える:

/**
 * POSTリクエスト: フォーム入力をデータベースに登録する。
 *
 * ステップ2との違い:
 *   ステップ2 → 受け取った値をそのままJSPに表示するだけ
 *   ステップ3 → 受け取った値をUserオブジェクトに詰めて、DAOでDBに登録
 */
protected void doPost(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {

    request.setCharacterEncoding("UTF-8");

    // ステップ2と同じ: フォームの値を受け取る
    String email = request.getParameter("email");
    String name = request.getParameter("name");
    String password = request.getParameter("password");

    // 【ステップ3で追加】受け取った値をDTOに詰める
    // → DAOに渡すための「入れ物」に変換する
    User user = new User();
    user.setEmail(email);
    user.setName(name);
    user.setPassword(password);

    // 【ステップ3で追加】DAOを使ってデータベースに登録
    UserDao userDao = new UserDao();
    boolean result = userDao.insert(user);

    System.out.println("登録結果: " + (result ? "成功" : "失敗") + " - " + name);

    // 登録後、フォーム画面に戻る
    RequestDispatcher dispatcher = request.getRequestDispatcher("/WEB-INF/form.jsp");
    dispatcher.forward(request, response);
}

ステップ2 → 3で変わった部分:

ステップ2: getParameter → setAttribute → JSP表示(DB無関係)
ステップ3: getParameter → User に詰める → UserDao.insert() → DB登録

3-2. FormServlet の import 文を追加

ファイル先頭の import に以下を追加する(UserDao と User を使うため):

import dao.UserDao;
import dto.User;

3-3. 動作確認

  1. サーバーを再起動
  2. http://localhost:8080/Hello/form にアクセス
  3. 適当な値を入力して「登録」ボタンを押す
  4. Eclipseのコンソールに「登録結果: 成功」と表示されることを確認
  5. Workbench で SELECT * FROM users; を実行し、入力した値が追加されていることを確認

ステップ 4: 成功・失敗で画面を切り替える

目的

登録が成功したら完了画面へ、失敗したらフォームに戻してエラーメッセージを表示する。

4-1. success.jsp の作成

WEB-INF フォルダに success.jsp を新規作成する。

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%-- User クラスを使うためにインポート --%>
<%@ page import="dto.User" %>
<%
    // サーブレットが setAttribute("user", user) で渡した User オブジェクトを取り出す
    // getAttribute の戻り値は Object 型なので (User) にキャストする
    User user = (User) request.getAttribute("user");
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>登録完了</title>
</head>
<body>
    <h1>登録が完了しました</h1>
    <table border="1">
        <tr>
            <th>メールアドレス</th>
            <td><%= user.getEmail() %></td>
        </tr>
        <tr>
            <th>名前</th>
            <td><%= user.getName() %></td>
        </tr>
    </table>
    <br>
    <%-- リンクをクリック → /form にGETリクエスト → FormServlet.doGet() → 空のフォーム表示 --%>
    <a href="${pageContext.request.contextPath}/form">続けて登録する</a>
</body>
</html>

4-2. form.jsp にエラーメッセージ表示を追加

form.jsp の <h1>ユーザー登録フォーム</h1> の下に以下を追加する:

<%
    // サーブレットが setAttribute("error", "...") でエラーメッセージを渡した場合のみ表示
    // 正常時(GET / 成功時)は setAttribute されていないので null → 表示しない
    String error = (String) request.getAttribute("error");
    if (error != null) {
%>
    <p style="color: red;"><%= error %></p>
<%
    }
%>

4-3. FormServlet の doPost を最終版に修正

doPost() を以下にすべて置き換える:

/**
 * POSTリクエスト: フォーム入力をDBに登録し、成功/失敗で画面を切り替える。
 *
 * ステップ3との違い:
 *   ステップ3 → 登録後、常にフォーム画面に戻る
 *   ステップ4 → 成功なら success.jsp、失敗なら form.jsp にエラーメッセージ付きで戻る
 */
protected void doPost(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {

    request.setCharacterEncoding("UTF-8");

    String email = request.getParameter("email");
    String name = request.getParameter("name");
    String password = request.getParameter("password");

    User user = new User();
    user.setEmail(email);
    user.setName(name);
    user.setPassword(password);

    UserDao userDao = new UserDao();
    boolean result = userDao.insert(user);

    // 【ステップ4で追加】登録結果によってフォワード先を切り替える
    if (result) {
        // 成功 → Userオブジェクトを渡して完了画面へ
        request.setAttribute("user", user);
        RequestDispatcher dispatcher = request.getRequestDispatcher("/WEB-INF/success.jsp");
        dispatcher.forward(request, response);
    } else {
        // 失敗 → エラーメッセージを渡してフォーム画面に戻す
        // form.jsp 側で getAttribute("error") が null でなければ赤字で表示する
        request.setAttribute("error",
                "登録に失敗しました。メールアドレスが重複している可能性があります。");
        RequestDispatcher dispatcher = request.getRequestDispatcher("/WEB-INF/form.jsp");
        dispatcher.forward(request, response);
    }
}

ステップ3 → 4で変わった部分:

ステップ3: insert() → 常に form.jsp に戻る
ステップ4: insert() → true なら success.jsp、false なら form.jsp + エラーメッセージ

4-4. 動作確認

成功パターン

  1. http://localhost:8080/Hello/form にアクセス
  2. 新しいメールアドレスで入力して「登録」
  3. 「登録が完了しました」画面が表示される

失敗パターン

  1. 「続けて登録する」リンクでフォームに戻る
  2. 同じメールアドレスで再度「登録」
  3. フォーム画面に戻り、赤字で「登録に失敗しました。メールアドレスが重複している可能性があります。」が表示される

完成後のファイル構成

Hello/src/main/
├── java/
│   ├── controller/
│   │   ├── HelloServlet.java      (既存: ユーザー表示)
│   │   ├── InsertServlet.java     (ステップ1で追加)
│   │   └── FormServlet.java       (ステップ2で追加、3・4で修正)
│   ├── dao/
│   │   └── UserDao.java           (既存 + ステップ1で insert 追加)
│   └── dto/
│       └── User.java              (既存: 変更なし)
└── webapp/WEB-INF/
    ├── web.xml                     (既存 + ステップ1・2でマッピング追加)
    ├── hello.jsp                   (既存: 変更なし)
    ├── form.jsp                    (ステップ2で追加、4でエラー表示追加)
    └── success.jsp                 (ステップ4で追加)

web.xml の最終形

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="https://jakarta.ee/xml/ns/jakartaee"
    xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_6_0.xsd"
    id="WebApp_ID" version="6.0">
  <display-name>Hello</display-name>

  <servlet>
      <servlet-name>HelloServlet</servlet-name>
      <servlet-class>controller.HelloServlet</servlet-class>
  </servlet>
  <servlet-mapping>
      <servlet-name>HelloServlet</servlet-name>
      <url-pattern>/hello</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
      <servlet-name>HelloServlet</servlet-name>
      <url-pattern>/</url-pattern>
  </servlet-mapping>

  <servlet>
      <servlet-name>InsertServlet</servlet-name>
      <servlet-class>controller.InsertServlet</servlet-class>
  </servlet>
  <servlet-mapping>
      <servlet-name>InsertServlet</servlet-name>
      <url-pattern>/insert</url-pattern>
  </servlet-mapping>

  <servlet>
      <servlet-name>FormServlet</servlet-name>
      <servlet-class>controller.FormServlet</servlet-class>
  </servlet>
  <servlet-mapping>
      <servlet-name>FormServlet</servlet-name>
      <url-pattern>/form</url-pattern>
  </servlet-mapping>
</web-app>
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?