【Java】JDBC URLをJavaでパースする

■ はじめに

JDBC URL(例えば「jdbc:mysql://localhost:3306/sampledb」)を、
ホスト、ポート、DB名などのようにパースしたい。

はじめ、以下の関連記事にある正規表現でパースすることを考えた。
https://blogs.yahoo.co.jp/dk521123/36604177.html
しかし、以下のサイトの回答をみたところ、もっと楽に実装できそうなので、
実装を試みる
https://stackoverflow.com/questions/9287052/how-to-parse-a-jdbc-url-to-get-hostname-port-etc?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa

アイディア

import java.net.URI;

public class Main {
  public static void main(String[] args) {
    try {
      String url = "jdbc:mysql://localhost:3306/sampledb01?useSSL=false&characterEncoding=UTF-8";
      String cleanURI = url.substring(5); // 「jdbc:」を差っ引く

      URI uri = URI.create(cleanURI);
      System.out.println("Scheme : " + uri.getScheme());
      System.out.println("Host : " + uri.getHost());
      System.out.println("Port : " + uri.getPort());
      System.out.println("Authority : " + uri.getAuthority());
      System.out.println("RawAuthority : " + uri.getRawAuthority());
      System.out.println("Fragment : " + uri.getFragment());
      System.out.println("RawFragment : " + uri.getRawFragment());
      System.out.println("Path : " + uri.getPath());
      System.out.println("RawPath : " + uri.getRawPath());
      System.out.println("Query : " + uri.getQuery());
      System.out.println("RawQuery : " + uri.getRawQuery());
      System.out.println("SchemeSpecificPart : " + uri.getSchemeSpecificPart());
      System.out.println("RawSchemeSpecificPart : " + uri.getRawSchemeSpecificPart());
      System.out.println("UserInfo : " + uri.getUserInfo());
      System.out.println("RawUserInfo : " + uri.getRawUserInfo());
    } catch (Exception ex) {
      ex.printStackTrace();
    }
  }
}
出力結果
Scheme : mysql
Host : localhost
Port : 3306
Authority : localhost:3306
RawAuthority : localhost:3306
Fragment : null
RawFragment : null
Path : /sampledb01
RawPath : /sampledb01
Query : useSSL=false&characterEncoding=UTF-8
RawQuery : useSSL=false&characterEncoding=UTF-8
SchemeSpecificPart : //localhost:3306/sampledb01?useSSL=false&characterEncoding=UTF-8
RawSchemeSpecificPart : //localhost:3306/sampledb01?useSSL=false&characterEncoding=UTF-8
UserInfo : null
RawUserInfo : null

■ サンプル

 * MySQL用のパースを作成
 * その他のDBは、自分でカスタマイズする必要がありそう
http://www.codejava.net/java-se/jdbc/jdbc-database-connection-url-for-common-databases

JdbcUrl.java

import java.net.URI;
import java.text.MessageFormat;

public class JdbcUrl {
  private static int DEFAULT_PORT = 3306;

  private String db;
  private String dbHost;
  private int dbPort;
  private String dbName;
  private String dbQuery;

  private JdbcUrl(String db, String dbHost, int dbPort, String dbName, String dbQuery) {
    this.db = db;
    this.dbHost = dbHost;
    this.dbPort = dbPort;
    this.dbName = dbName;
    this.dbQuery = dbQuery;
  }

  public static JdbcUrl parse(String url) {
    if (url == null) {
      throw new IllegalArgumentException("null");
    }
    String cleanUri = url.substring(5);
    URI uri = URI.create(cleanUri);
    return new JdbcUrl(uri.getScheme(), uri.getHost(), uri.getPort(), uri.getPath().replaceAll("/", ""),
        uri.getQuery());
  }

  public String getDb() {
    return this.db;
  }

  public String getDbHost() {
    return this.dbHost;
  }

  public int getDbPort() {
    if (this.dbPort == -1) {
      return DEFAULT_PORT;
    }
    return this.dbPort;
  }

  public String getDbPortString() {
    return String.valueOf(this.getDbPort());
  }

  public String getDbName() {
    return this.dbName;
  }

  public String getDbQuery() {
    return this.dbQuery;
  }

  @Override
  public String toString() {
    if (this.getDbQuery() == null) {
      return MessageFormat.format("jdbc:{0}://{1}:{2}/{3}", this.getDb(), this.getDbHost(), this.getDbPortString(),
          this.getDbName());
    } else {
      return MessageFormat.format("jdbc:{0}://{1}:{2}/{3}?{4}", this.getDb(), this.getDbHost(), this.getDbPortString(),
          this.getDbName(), this.getDbQuery());
    }
  }
}

Main.java

public class Main {
  public static void main(String[] args) {
    try {
      JdbcUrl jdbcUrl1 = JdbcUrl.parse("jdbc:mysql://localhost:3306/sampledb01?useSSL=false&characterEncoding=UTF-8");
      print(jdbcUrl1);
      JdbcUrl jdbcUrl2 = JdbcUrl.parse("jdbc:mysql://127.0.0.1:13306/sampledb02");
      print(jdbcUrl2);
      JdbcUrl jdbcUrl3 = JdbcUrl.parse("jdbc:mysql://sample.co.jp/sampledb03");
      print(jdbcUrl3);
      
    } catch (Exception ex) {
      ex.printStackTrace();
    }
  }
  
  private static void print(JdbcUrl jdbcUrl) {
    System.out.println(jdbcUrl.getDbHost());
    System.out.println(jdbcUrl.getDbPort());
    System.out.println(jdbcUrl.getDbName());
    System.out.println(jdbcUrl.getDbQuery());
    System.out.println(jdbcUrl.toString());
    System.out.println("**************************");
  }
}
出力結果
localhost
3306
sampledb01
useSSL=false&characterEncoding=UTF-8
jdbc:mysql://localhost:3306/sampledb01?useSSL=false&characterEncoding=UTF-8
**************************
127.0.0.1
13306
sampledb02
null
jdbc:mysql://127.0.0.1:13306/sampledb02
**************************
sample.co.jp
3306
sampledb03
null
jdbc:mysql://sample.co.jp:3306/sampledb03
**************************

関連記事

Java正規表現 [4] 文字列の抽出 ~Matcher.group() ~

https://blogs.yahoo.co.jp/dk521123/36604177.html