TomcatとPostgreSQLをdocker-composeで起動してDBのデータを取得するJavaサーブレットを実行する

docker docker
スポンサーリンク

Tomcatでサービスを立ち上げて、PostgreSQLのDBからデータを取得してみようと思いました。

docker-composeでTomcatとPostgreSQLを起動すれば、簡単に環境を構築できそうです。

サンプルを例に、やり方を紹介します。

docker-composeでTomcatとPostgreSQLを起動

docker-compose.ymlの作成

TomcatとPostgreSQLをdockerで立ち上げます。

version: '3'

services:
  app:
    container_name: tomcat
    build: ./tomcat
    ports:
      - "8080:8080"

  db:
    container_name: postgresql
    build: ./postgresql
    ports:
      - 5432:5432
    volumes:
      - ./postgresql/init:/docker-entrypoint-initdb.d
    environment:
      POSTGRES_USER: user
      POSTGRES_PASSWORD: pass
    restart: always

docker-compose.ymlのbuildでそれぞれのサービスのDockerfileがあるディレクトリを指定しています。

フォルダ構成は以下の通りです。

.
├── docker-compose.yml
├── postgresql
│   ├── Dockerfile
│   └── init
│       └── init.sql
└── tomcat
    ├── Dockerfile
    └── webapps
        └── jdbc-sample.war

それぞれの設定はこんな感じです。

使用するサンプルプログラム

Tomcatにデプロイするjdbc-sample.warを作成します。

サンプルプログラムは、こちらの記事で使用したものを流用します。
mavenで作成していますので、mvn installでwarファイルを生成してください。

DBのテーブルをHTMLで出力するサーブレットです。

package com.example;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

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

@SuppressWarnings("serial")
public class DBServlet extends HttpServlet {
    static final String DB_URL = "jdbc:postgresql://postgresql:5432/docker";
    static final String DB_USER = "user";
    static final String DB_PASS = "pass";
    static final String QUERY = "SELECT id,name FROM book";

    @Override
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException {
        response.setContentType("text/html; charset=UTF-8");
        try {
            Class.forName("org.postgresql.Driver");
            try(Connection conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASS);
                Statement stmt = conn.createStatement();
                ResultSet rs = stmt.executeQuery(QUERY);
                PrintWriter pw = response.getWriter();) {
                pw.println("<html>");
                pw.println("<head><title>show table</title></head>");
                pw.println("<body><table border=1>");
                pw.println("<tr><th>id</th><th>name</th></tr>");
                while (rs.next()) {
                    pw.println("<tr>");
                    pw.println("<td>" + rs.getInt("id") + "</td>");
                    pw.println("<td>" + rs.getString("name") + "</td>");
                    pw.println("</tr>");
                }
                pw.println("</table></body>");
                pw.println("</html>");
            } catch (SQLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

}

データベース接続URLのホストがcontainer_nameであることに注意してください。
“jdbc:postgresql://<container_name>:<port>/<database_name>”

docker-composeで起動したネットワーク内では、ホストにlocalhostではなくcontainer_nameを指定します。ハマりポイントだと思いますので、気をつけてください。

サービスを立ち上げてDBのデータを取得

docker-compose up -d

-dオプションをつけるとバックグラウンドで実行されます。

ブラウザでURLの接続して、DBのテーブルデータが表示されればOKです。

私の作成したwarファイルでは、http://localhost:8080/jdbc-sample/DBServletで確認できます。

無事、Tomcatで立ち上げたJavaサーブレットからDBに接続できました。

確認できたら、dockerを停止しましょう。

docker-compose down --rmi local

–rmi localのオプションをつけると、Dockerfileで作成したイメージも削除してくれます。

以上。終わりです。

コメント

タイトルとURLをコピーしました