Java Webアプリケーションにおける学生情報登録機能の実装

本稿では、ServletおよびJDBCを活用したJava Webアプリケーションにおいて、学生情報をデータベースに登録する機能の実装プロセスについて解説します。MVC(Model-View-Controller)アーキテクチャに基づき、データの永続化から画面表示までのフローを構築します。

1. データベース接続ユーティリティ

最初に、データベースとの接続を確立し、管理するためのユーティリティクラスを定義します。このクラスはJDBCドライバのロードおよび`Connection`オブジェクトの取得を担当します。

package com.util;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class DBConnectionManager {
    private static final String DB_URL = "jdbc:mysql://localhost:3306/student_db?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Tokyo&useSSL=false";
    private static final String DB_USER = "root";
    private static final String DB_PASS = "password";

    public static Connection getConnection() throws SQLException {
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            throw new SQLException("Database Driver Not Found", e);
        }
        return DriverManager.getConnection(DB_URL, DB_USER, DB_PASS);
    }
}

2. データモデル(Entity)

学生情報を保持するためのJavaBeans(DTO)クラスです。画面から送信されるデータを格納するプロパティと、アクセッサメソッドを定義します。

package com.model;

public class Student {
    private String loginId;
    private String password;
    private String fullName;
    private String studentNumber;
    private String gender;
    private String phoneNumber;
    private String emailAddress;
    private String department;
    private String major;
    private String className;
    private String enrollmentYear;
    private String homeTown;
    private String remarks;

    // Getters and Setters
    public String getLoginId() { return loginId; }
    public void setLoginId(String loginId) { this.loginId = loginId; }
    public String getPassword() { return password; }
    public void setPassword(String password) { this.password = password; }
    public String getFullName() { return fullName; }
    public void setFullName(String fullName) { this.fullName = fullName; }
    public String getStudentNumber() { return studentNumber; }
    public void setStudentNumber(String studentNumber) { this.studentNumber = studentNumber; }
    public String getGender() { return gender; }
    public void setGender(String gender) { this.gender = gender; }
    public String getPhoneNumber() { return phoneNumber; }
    public void setPhoneNumber(String phoneNumber) { this.phoneNumber = phoneNumber; }
    public String getEmailAddress() { return emailAddress; }
    public void setEmailAddress(String emailAddress) { this.emailAddress = emailAddress; }
    public String getDepartment() { return department; }
    public void setDepartment(String department) { this.department = department; }
    public String getMajor() { return major; }
    public void setMajor(String major) { this.major = major; }
    public String getClassName() { return className; }
    public void setClassName(String className) { this.className = className; }
    public String getEnrollmentYear() { return enrollmentYear; }
    public void setEnrollmentYear(String enrollmentYear) { this.enrollmentYear = enrollmentYear; }
    public String getHomeTown() { return homeTown; }
    public void setHomeTown(String homeTown) { this.homeTown = homeTown; }
    public String getRemarks() { return remarks; }
    public void setRemarks(String remarks) { this.remarks = remarks; }
}

3. DAO(Data Access Object)

データベース操作(INSERT文の実行)を行うDAOクラスです。セキュリティ向上のため、文字列連結によるSQL構築ではなく、`PreparedStatement`を用いてプレースホルダーに値をセットする方式を採用します。

package com.dao;

import com.model.Student;
import com.util.DBConnectionManager;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class StudentRepository {
    private static final String SQL_INSERT = 
        "INSERT INTO student_table (login_id, pass, name, student_no, gender, tel, email, dept, major, class_name, year, hometown, note) " +
        "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";

    public boolean register(Student student) {
        boolean isSuccess = false;
        try (Connection conn = DBConnectionManager.getConnection();
             PreparedStatement pstmt = conn.prepareStatement(SQL_INSERT)) {
            
            pstmt.setString(1, student.getLoginId());
            pstmt.setString(2, student.getPassword());
            pstmt.setString(3, student.getFullName());
            pstmt.setString(4, student.getStudentNumber());
            pstmt.setString(5, student.getGender());
            pstmt.setString(6, student.getPhoneNumber());
            pstmt.setString(7, student.getEmailAddress());
            pstmt.setString(8, student.getDepartment());
            pstmt.setString(9, student.getMajor());
            pstmt.setString(10, student.getClassName());
            pstmt.setString(11, student.getEnrollmentYear());
            pstmt.setString(12, student.getHomeTown());
            pstmt.setString(13, student.getRemarks());

            int rowsAffected = pstmt.executeUpdate();
            if (rowsAffected > 0) {
                isSuccess = true;
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return isSuccess;
    }
}

4. Servlet(Controller)

クライアントからのリクエストを受け取り、パラメータを解析してStudentオブジェクトを生成し、DAOの登録メソッドを呼び出します。その結果に応じて適切なビュー(JSP)へ転送します。

package com.controller;

import com.dao.StudentRepository;
import com.model.Student;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/RegisterServlet")
public class RegisterController extends HttpServlet {
    private static final long serialVersionUID = 1L;
    
    private StudentRepository studentDao = new StudentRepository();

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("UTF-8");
        
        Student student = new Student();
        student.setLoginId(request.getParameter("uid"));
        student.setPassword(request.getParameter("pwd"));
        student.setFullName(request.getParameter("uname"));
        student.setStudentNumber(request.getParameter("sno"));
        student.setGender(request.getParameter("gender"));
        student.setPhoneNumber(request.getParameter("phone"));
        student.setEmailAddress(request.getParameter("email"));
        student.setDepartment(request.getParameter("dept"));
        student.setMajor(request.getParameter("major"));
        student.setClassName(request.getParameter("cls"));
        student.setEnrollmentYear(request.getParameter("year"));
        student.setHomeTown(request.getParameter("hometown"));
        student.setRemarks(request.getParameter("memo"));

        boolean result = studentDao.register(student);
        
        if (result) {
            request.setAttribute("msg", "登録が完了しました");
        } else {
            request.setAttribute("msg", "エラーが発生しました、またはIDが重複しています");
        }
        
        request.getRequestDispatcher("result.jsp").forward(request, response);
    }
}

5. ビュー(JSP)

ユーザー入力を受け付けるフォーム画面です。JavaScriptによる入力値のバリデーション(形式チェック)を実装し、サーバー側へデータを送信します。

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>学生登録システム</title>
</head>
<body>
    <div class="form-container">
        <form action="RegisterServlet" method="post" onsubmit="return validateForm()">
            <fieldset>
                <legend>新規学生登録</legend>
                
                <label>ログインID: </label>
                <input type="text" name="uid" id="uid" required><br>
                
                <label>パスワード: </label>
                <input type="password" name="pwd" id="pwd" required><br>
                
                <label>氏名: </label>
                <input type="text" name="uname" id="uname"><br>
                
                <label>学籍番号: </label>
                <input type="text" name="sno" id="sno"><br>
                
                <label>性別: </label>
                <input type="radio" name="gender" value="male">男
                <input type="radio" name="gender" value="female">女<br>
                
                <label>電話番号: </label>
                <input type="text" name="phone" id="phone"><br>
                
                <label>メールアドレス: </label>
                <input type="text" name="email" id="email"><br>
                
                <label>学科: </label>
                <input type="text" name="dept" id="dept"><br>
                
                <label>専攻: </label>
                <input type="text" name="major" id="major"><br>
                
                <label>クラス: </label>
                <input type="text" name="cls" id="cls"><br>
                
                <label>入学年度: </label>
                <select name="year">
                    <option value="2020">2020</option>
                    <option value="2021">2021</option>
                    <option value="2022">2022</option>
                    <option value="2023">2023</option>
                </select><br>
                
                <label>出身地: </label>
                <input type="text" name="hometown" id="hometown"><br>
                
                <label>備考: </label>
                <input type="text" name="memo" id="memo"><br>
                
                <button type="submit">登録</button>
            </fieldset>
        </form>
    </div>

    <script>
        function validateForm() {
            var uid = document.getElementById("uid").value;
            var pwd = document.getElementById("pwd").value;
            var sno = document.getElementById("sno").value;
            var phone = document.getElementById("phone").value;
            var email = document.getElementById("email").value;
            
            // ID validation: 6-12 alphanumeric
            var uidRegex = /^[a-zA-Z][a-zA-Z0-9]{5,11}$/;
            if (!uidRegex.test(uid)) {
                alert("IDは英字で始まり6〜12文字の英数字で入力してください");
                return false;
            }
            
            // Password validation: more than 8 alphanumeric
            if (pwd.length <= 8 || /[^a-zA-Z0-9]/.test(pwd)) {
                alert("パスワードは8文字以上の英数字で入力してください");
                return false;
            }

            // Student ID validation: 8 digits
            if (!/^\d{8}$/.test(sno)) {
                alert("学籍番号は8桁の数字で入力してください");
                return false;
            }

            // Phone validation: 11 digits
            if (!/^\d{11}$/.test(phone)) {
                alert("電話番号は11桁の数字で入力してください");
                return false;
            }

            // Email validation
            var emailRegex = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/;
            if (!emailRegex.test(email)) {
                alert("正しいメールアドレス形式を入力してください");
                return false;
            }
            
            return true;
        }
    </script>
</body>
</html>

6月20日 17:57 投稿