Java Java Todo Webアプリ開発

【Javaサーブレット&jsp入門#3】Select文を実行してPostgreSQLからデータを取得して一覧表示する

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

ウハブログ

こんにちは、大学時代にプログラミングを始め、現在はエンジニアをしているuhablog(ウハブログ)です。

今回の記事はこちらの記事の続きとなっております。
サーブレットとjspを使ってTodoWebアプリケーションを作成します。
今回は実際にテーブルからデータを取得してWebブラウザ上で一覧表示してみます。

今回は

  • home.htmlにformを作成しListServletにリクエストを送る
  • ListServletでリクエストを受け取り、データベースからデータを取得
  • list.jspでデータを表示

という流れで開発を進めていきます。

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

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

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

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

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

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

    home.html

    最初の画面になります。非常にシンプルな作りです。

    <h1>タグを使ったタイトルを表示します。

    formによって「Todo一覧を表示」と書かれたボタンを表示します。
    これが押されるとactionに指定したlist-servletに処理が移ります。

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Home</title>
    </head>
    <body>
        <h1>Todo 管理Webアプリケーション</h1>
        <form action="list-servlet" method="get">
            <input type="submit" value="Todo一覧を表示">
        </form>
    </body>
    </html>

    TodoListDAOの作成

    実際にPostgreSQLに接続し、Todoの一覧を取得するメソッドを持つクラスを作成します。
    model.daoパッケージの中にTodoListDAO.javaを作成します。中身は次のようにします。

    package model.dao;
    
    import java.sql.Connection;
    import java.sql.Date;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.util.ArrayList;
    import java.util.List;
    
    import model.DBConnection;
    import model.dao.dto.TodoDTO;
    
    /**
     * Todoの一覧を取得するクラス
     *
     * @author yuhablog
     */
    public class TodoListDAO {
    
        /**
         * Todoの一覧を取得する
         * @return todoの一覧
         * @throws ClassNotFoundException
         * @throws SQLException
         */
        public List<TodoDTO> getTodoList() throws ClassNotFoundException, SQLException {
            // 返却用Listの初期化
            List<TodoDTO> todoList = new ArrayList<>();
    
            // 実行するSQL
            String sql = "SELECT id, todo, timeLimit from todo";
    
            // DBに接続し、Todo一覧を取得する
            try (Connection con = DBConnection.getConnection();
                    PreparedStatement pstmt = con.prepareStatement(sql)) {
    
                // SQLを実行しResultSetの変数に結果を格納する
                ResultSet res = pstmt.executeQuery();
                // 実行結果を順番に取り出す
                while (res.next()) {
                    //  それぞれid, todo, timeLimitを取得する
                    int id = res.getInt("id");
                    String todo = res.getString("todo");
                    Date timeLimit = res.getDate("timeLimit");
    
                    // 取得したid, todo, timeLimitでTodoDTOを初期化してListに追加
                    todoList.add(new TodoDTO(id, todo, timeLimit));
                }
            }
            return todoList;
        }
    }

    データベースへの接続

    前回の記事↗︎で作成したgetConnectionメソッドを呼び出してPostgreSQLへの接続を取得します。

    次にString型のSQLを実際にPostgreSQLで実行するためにprepareStatementメソッドに引数としてsqlを渡します。

    これらを行っているのが、try直後の()内の処理です。

    try (Connection con = DBConnection.getConnection();
        PreparedStatement pstmt = con.prepareStatement(sql))

    SQLの実行

    そして実際にSQLの実行を行うのが次の記述です。

    今回はSELECT文を実行しているので、ResultSet型の変数を用意して結果を受け取ります。
    この変数resの中にSELECT文の実行によって取得できたデータが格納されます。

    // SQLを実行しResultSetの変数に結果を格納する
    ResultSet res = pstmt.executeQuery();

    結果の取得

    次の記述でSELECTによって取得したデータを返却用の変数todoListに追加していきます。

    結果が格納されたresに対して様々なメソッドを呼び出します。

    nextメソッドで次にデータがある場合はwhile内の処理が実行されます。
    res.getXXXメソッドで引数で指定したカラムの値を取り出せます。
    XXXの部分をデータ型に合わせて変更していきます。

    取得したデータを前回↗︎作成したTodoDTOのコンストラクタに渡して、それをtodoListに追加します。

    PostgreSQLから取得したTodoを全てtodoListに追加し終わるとwhileループを抜けます。

    // 実行結果を順番に取り出す
    while (res.next()) {
        //  それぞれid, todo, timeLimitを取得する
        int id = res.getInt("id");
        String todo = res.getString("todo");
        Date timeLimit = res.getDate("timeLimit");
    
        // 取得したid, todo, timeLimitでTodoDTOを初期化してListに追加
        todoList.add(new TodoDTO(id, todo, timeLimit));
    }

    PostgreSQLからSelectするListServlet

    home.htmlから送られてくるリクエストを元にPostgreSQLからtodoの一覧を取得し、結果を表示するための処理を記述したListServletを作成します。

    まずはサーブレットを作ります。
    srcフォルダの中にservletというパッケージを作成してください。
    その後右クリックをして新規→その他を選択します。

    次にWebのなかにあるサーブレットを選択します。

    クラス名をListServletと入力して次へを押します。そのまま進んで完了を押します。

    すると新しくListServlet.javaが作られます。

    リクエスト先の設定

    ListServlet.java13行目の@WebServletのなかの("/ListServlet")を("/list-servlet")に変更します。
    これは先ほど作ったhome.htmlのformタグのactionでlist-servletにリクエストが投げられるように設定したからです。

    doGetメソッドの中を編集

    そして28行目あたりからdoGetメソッドが書かれているはずです。

    先ほどのformでメソッドをgetにしたためformが提出されるとdoGetメソッドが実行されます。
    formのなかのメソッドをPOSTにしていた場合は36行目からのdoPostメソッドが実行されます。

    今回作るdoGetメソッドの中身は以下のようになります。順番に解説していきます。

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // todoの一覧を保持する変数を宣言
        List<TodoDTO> todoList = new ArrayList<>();
    
        // DAOを生成し、Todo一覧を取得する
        TodoListDAO dao = new TodoListDAO();
        try {
            // todo一覧を取得する
            todoList = dao.getTodoList();
        }catch(SQLException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    
        // todo一覧をリクエストスコープに設定する
        request.setAttribute("todoList", todoList);
        // todo一覧画面に遷移する
        RequestDispatcher rd = request.getRequestDispatcher("list.jsp");
        rd.forward(request, response);
    }

    まずは先ほど作成したDAOをインスタンス化し、getTodoListメソッドを呼び出します。
    戻り値をTodoDTOのListであるtodoListに格納します。

    // DAOを生成し、Todo一覧を取得する
    TodoListDAO dao = new TodoListDAO();
    try {
        // todo一覧を取得する
        todoList = dao.getTodoList();
    }catch(SQLException | ClassNotFoundException e) {
        e.printStackTrace();
    }

    次に取得したtodo一覧をjsp側でも扱えるようにしたいのでリクエストスコープにtodoListを設定します。
    このスコープという概念はJavaでWebアプリを作成する上で非常に重要な概念になります。

    リクエストスコープは1リクエスト毎に生成されます。
    簡単に説明すると1回のリクエストの間だけ使えるデータの保存場所みたいなノリです。
    Qiitaにまとまった記事があるので時間がある方は読んでみると理解が深まります。

    // todo一覧をリクエストスコープに設定する
    request.setAttribute("todoList", todoList);

    request.getRequestDispatcherによって次にどこに処理を移すか指示しています。
    引数でlist.jspを指定したのでfowardメソッドを使うことで指定したURLに処理を移すことができます。

    RequestDispatcher rd = request.getRequestDispatcher("list.jsp");
    rd.forward(request, response);

    list.jsp

    サーブレットからforwardされてlist.jspに処理が移ります。
    全体のコードは次のようになります。

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8" import="java.util.List, java.util.ArrayList, model.dao.dto.TodoDTO"%>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Todo List</title>
    </head>
    <body>
        <%
            List<TodoDTO> todoList = (List) request.getAttribute("todoList");
        %>
        <% for(TodoDTO todo: todoList){  %>
            <%=todo.getTodo() %> 期限:<%=todo.getTimeLimit() %><br>
        <% } %>
    </body>
    </html>

    まずこのjsp内でもListを使いたいので一番初めにインポートします。
    またTodoDTOも利用するのでこちらも合わせてインポートしておきます。

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8" import="java.util.List, java.util.ArrayList, model.dao.dto.TodoDTO"%>

    bodyタグの中身です。
    まずは先ほどのサーブレットで作成したtodoListを取り出します。

    jspでは<%%>の間にJavaのコードを記述することができます。

    requestのgetAttributeメソッドを使うことでリクエストスコープからデータの取得を行うことが可能です。
    先ほどサーブレットでリクエストスコープにtodoListを設定したので、これをjspで取り出しています。
    getAttributeの引数はsetAttributeしたときの第一引数と一致している必要があります。

    <%
        List<TodoDTO> todoList = (List) request.getAttribute("todoList");
    %>

    for文でtodoListの要素を一つづつ取り出して表示していきます。
    非常に読みにくいですが、先ほどと同じく<%%>の間にJavaのコードが記述されています。
    <%=todo.getTodo() %>のところにはtodo.getTodo()の戻り値が表示されるようになります。

    <% for(TodoDTO todo: todoList){ %>
        <%=todo.getTodo() %> 期限:<%=todo.getTimeLimit() %><br>
    <% } %>

    動作確認

    ここまでコードがかけたら実際にサーバーを起動してWebブラウザで確認してみます。
    home.htmlを右クリックして「実行」→「サーバで実行」を選択します。

    サーバを選択し、完了をクリックします。
    するとコンソールに何やら文字がいっぱい出てきた後自動でWebブラウザが立ち上がります。

    おそらく下記画像のようなページが出てきます。

    「Todo一覧を表示」ボタンを押すと画面遷移して下記のような感じでデータベースに保存してあったデータが取り出され表示されます。
    CSSを書いていないのでなんとも物寂しい見てくれですが、そこは追々整えていけばいいでしょう。

    エラー対応

    この記事を参考にTodoアプリを作成していただいている方からDBに接続できないエラーが発生するとのご指摘をいただきました。
    ここで動作確認を行った際にClassNotFoundExceptionが発生した場合にはプロジェクト内のWEB-INF/libフォルダの中にjdbcドライバを格納してください。

    質問していただいた方ありがとうございます。
    他にも質問ある方いらしたらお気軽にツイッターまでお願いいたします。

    次回予告

    次回はTodoを登録する機能を作成します。

    ToDoを新規作成する

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

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

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

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

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

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

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

    Freeks公式サイトはこちら>>>

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

    -Java, Java Todo Webアプリ開発
    -, , , , ,