Java データベース

【Java】データベースに接続したログイン機能を作る

※アフィリエイト広告を利用しています。

今回の記事ではJavaでデータベース(PostgreSQL)に接続してユーザー認証を行うログイン機能を作っていきます。

開発環境にはeclipseを使用します。
また前提として既に動的Webプロジェクトが作成済みであること、PostgreSQLにユーザーの情報が入ったテーブルがあることとします。
動的Webプロジェクトの作成についてはこちらの記事をPostgreSQLでのテーブル作成はこちらの記事を参考にしてみてください。

挫折せずにプログラミングを学ぶために必要なこと

僕はプログラミングで挫折した経験があります。

それは周りに聞ける人がいなく、一人でエラーと戦っていたからです。

Freeksは月額10,780円という破格の値段で、現役エンジニアに質問する環境を手に入れることができるプログラミングスクールです。

次のような悩みを少しでも抱えていたら、まずは無料カウンセリングを受けてみてください。

  • エラーを一人で解消できない
  • このまま勉強を続けて本当に就職できるかわからない
  • プログラミングスクールは高額すぎて通えない
  • 申込みは1分でできます。学習する環境にお金を使うというのは良い自己投資になります。
    >>Freeksの無料カウンセリングはこちら

    今回作るログイン機能の全体像

    今回作成するログイン機能の全体像を簡単に説明します。

    ブラウザに表示する画面はログイン情報を入力する画面とログイン後に遷移する画面の2種類です。

    まずログイン情報を入力する画面でユーザーIDとパスワードの入力を行います。

    入力された情報を元にDBに接続してユーザーIDとパスワードが一致したユーザーがいた場合はログイン成功の画面に遷移します。

    一致したユーザーがいなかった場合はログイン画面にエラーメッセージの表示を行います。

    ログイン画面の作成

    まずはログイン画面を作っていきましょう。ユーザーIDとパスワードを入力する簡単なフォームを用意します。
    WebContentの中にlogin.jspを作成します。
    その上でbodyタグ内を以下のように追加します。

    <!-- login.jspのbodyの中を以下の通り編集 -->
    <!-- リクエストスコープからエラーメッセージを受け取る -->
    <%String failureMessage = (String)request.getAttribute("loginFailure"); %>
    
    <!-- エラーメッセージが存在するときだけ表示する -->
    <% if (failureMessage != null) {%>
        <%=failureMessage %>
    <%} %>
    
    <!-- ログインフォーム。ユーザーIDとパスワードの入力を行う -->
    <form action="Login" method="post">
        <input type="text" name="user_id">
        <input type="password" name="password">
        <input type="submit" value="ログイン">
    </form>
    

    はじめにリクエストスコープからエラーメッセージを受け取っています。そしてエラーメッセージが存在した時のみ画面に表示します。

    <!-- login.jspのbodyの中を以下の通り編集 -->
    <!-- リクエストスコープからエラーメッセージを受け取る -->
    <%String failureMessage = (String)request.getAttribute("loginFailure"); %>
    
    <!-- エラーメッセージが存在するときだけ表示する -->
    <% if (failureMessage != null) {%>
        <%=failureMessage %>
    <%} %>

    フォームではユーザーIDをuser_idという名前で送り、パスワードをpasswordという名前でサーブレット側に送ります。

    <!-- ログインフォーム。ユーザーIDとパスワードの入力を行う -->
    <form action="Login" method="post">
        <input type="text" name="user_id">
        <input type="password" name="password">
        <input type="submit" value="ログイン">
    </form>

    formを使ってユーザーIDとパスワードをサーバーに送信する

    サーブレットの作成

    次に画面から送られてきたユーザーIDとパスワードを元に認証処理を行うサーブレットを作成します。

    srcフォルダの中にloginパッケージを作成しLoginServletを作成します。
    パスはなんでも大丈夫ですが、今回は「/Login」としました。

    サーブレットを作成するときに指定したパスとログイン画面のformタグのaction属性には同じ値を設定する必要がある

    今回はGETメソッドでリクエストが来たときに呼ばれるdoGetメソッドとPOSTメソッドでリクエストが来たときに呼ばれるdoPostメソッドを作っていきます。

    doGetメソッドでログイン画面を表示する

    まずdoGetメソッドは以下のようにします。

    /**
     * Getでリクエストが来たときの処理
     * login.jspを画面に表示する
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.getRequestDispatcher("login.jsp").forward(request, response);
    }

    今回のdoGetメソッドはシンプルです。GETメソッドのリクエストを受け取った後、login.jspを画面に表示します。

    request.getRequestDispatcher("login.jsp").forward(request, response);

    doPostメソッドでログインの認証を行う

    次にdoPostメソッドの作成を行います。内容は以下の通りです。

    /**
     * 送られてきたユーザーIDとパスワードを元にDBに接続しログイン認証を行う
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
        // ユーザーから送信されたユーザーIDとパスワードを取得する。
        String userId = request.getParameter("user_id");
        String password = request.getParameter("password");
    
        // ログイン認証後に遷移する先を格納する
        String path = "";
    
        try {
            // PostgreSQLに接続するためのURL
            String url = "jdbc:postgresql://localhost:5432/yourDbName";
            String user = "yourUserName";
            String pass = "yourPassowrd";
    
            /*
             * 実行するSQL
             * idとpasswordが一致するユーザーのidをとってくる
             */
            String sql = "SELECT id FROM users WHERE id=? AND password=?";
    
            // PostgreSQLに接続する
            Class.forName("org.postgresql.Driver");
            try (Connection con = DriverManager.getConnection(url, user, pass);
                    PreparedStatement pstmt = con.prepareStatement(sql)) {
    
                // 入力されたユーザーIDとパスワードをSQLの条件にする
                pstmt.setString(1, userId);
                pstmt.setString(2, password);
    
                // SQLの実行
                ResultSet res = pstmt.executeQuery();
    
                // ユーザーIDとパスワードが一致するユーザーが存在した時
                if (res.next()) {
                    // user_idをリクエストスコープに設定する
                    request.setAttribute("user_id", res.getString("id"));
    
                    // ログイン成功画面に遷移する
                    path = "loginSuccess.jsp";
                } else {
                    // ログイン失敗の文言を追加する
                    request.setAttribute("loginFailure", "ログインに失敗しました");
    
                    // ログインに失敗したときはもう一度ログイン画面を表示する
                    path = "login.jsp";
                }
            }
        }catch (ClassNotFoundException | SQLException e) {
            e.printStackTrace();
        }
    
        RequestDispatcher rd = request.getRequestDispatcher(path);
        rd.forward(request, response);
    }

    はじめに送られてきたユーザーIDとパスワードをそれぞれuserID, passwordという変数に格納しています。

    // ユーザーから送信されたユーザーIDとパスワードを取得する。
    String userId = request.getParameter("user_id");
    String password = request.getParameter("password");

    その後PostgreSQLに接続するために必要な値を変数宣言して格納します。

    // PostgreSQLに接続するためのURL
    String url = "jdbc:postgresql://localhost:5432/yourDbName";
    String user = "yourUserName";
    String pass = "yourPassowrd";

    次に今回実行するSQL文を作成します。
    今回はidとパスワードが一致するユーザーデータのidをDBから取り出します。

    /*
     * 実行するSQL
     * idとpasswordが一致するユーザーのidをとってくる
     */
    String sql = "SELECT id FROM users WHERE id=? AND password=?";

    DBに接続し、SQLを実行します。

    // PostgreSQLに接続する
    Class.forName("org.postgresql.Driver");
    try (Connection con = DriverManager.getConnection(url, user, pass);
            PreparedStatement pstmt = con.prepareStatement(sql)) {
    
        // 入力されたユーザーIDとパスワードをSQLの条件にする
        pstmt.setString(1, userId);
        pstmt.setString(2, password);
    
        // SQLの実行
        ResultSet res = pstmt.executeQuery();

    idとパスワードが一致しているユーザーが存在していた場合、res.next()がtrueになります。
    この中で、ログインが成功した時の処理を記述します。

    反対に、ユーザーが存在しなかった場合はres.next()がfalseになるので、ログイン失敗時の処理を記述します。

    // ユーザーIDとパスワードが一致するユーザーが存在した時
    if (res.next()) {
        // user_idをリクエストスコープに設定する
        request.setAttribute("user_id", res.getString("id"));
        // ログイン成功画面に遷移する
        path = "loginSuccess.jsp";
    } else {
        // ログイン失敗の文言を追加する
        request.setAttribute("loginFailure", "ログインに失敗しました");
    
        // ログインに失敗したときはもう一度ログイン画面を表示する
        path = "login.jsp";
    }

    最後に設定されたパスに遷移してサーブレット内での処理は終了になります。

    RequestDispatcher rd = request.getRequestDispatcher(path);
    rd.forward(request, response);

    ログイン成功画面

    最後に認証に成功したのちに遷移するログイン成功画面を作成します。
    loginn.jspと同じくWebContent内にloginSuccess.jspを作成します。
    bodyタグ内を以下のように書き換えます。

    <!-- リクエストスコープからログインユーザーのIDを取得する -->
    <%String userId = (String)request.getAttribute("user_id"); %>
    
    <!-- メッセージを表示する -->
    <h1>ログイン成功!!</h1>
    <h2>こんにちは!<%=userId %>さん</h2>

    動作確認

    動作確認を行います。サーバーを起動し、ブラウザで「http://localhost:8080/JavaWebApplicationSample/Login」にアクセスします。
    すると殺風景ではありますがログインフォームが表示されます。

    ユーザーIDとパスワードの入力を行い、ログインボタンを押すと認証処理がされます。
    認証に成功した場合はログイン成功画面に遷移し、失敗した場合はログイン画面に戻り、エラーメッセージが表示されます。

    ログイン成功時

    ログイン失敗時

    以上でJavaでデータベースを使ったログイン機能の実装を終わります。

    挫折せずにプログラミングを学ぶためには?

    僕はプログラミングで挫折した経験があります。

    エラーの連続やエラーが解消しても思った通りに動かないといったことが原因で、プログラミングが嫌いでした。

    「プログラミングって全然意味わからないし、全然楽しくない」そう思っていました。

    原因は当時周りに聞ける人が誰もいなかったからです。

    プログラミング学習をしていく上で周りに聞ける環境というのはとても大切です。

    周りに聞ける人なんていない

    そんな人におすすめなのが月額10,780円で現役エンジニアに質問できる、プログラミングスクールのFreeksです。

    多くのプログラミングスクールが数十万円払って通うところを月額10,780円から通うことができるのはコスパが良いです。

    しかもサブスク制で、自分のペースで学ぶことができ嫌になったらすぐにやめることができます。

    「周りに誰も聞ける人がいなくて、エラーが解決できない」「プログラミング全然楽しくない」という方は、無料カウンセリングを受けてみて下さい。

    \\サブスク型スクールで挫折せずにエンジニアになろう//

    Freeks公式サイトはこちら

    まずは無料カウンセリングから

    【関連記事】Freeks評判、口コミ

    -Java, データベース
    -