45

How can I parse a JDBC URL (oracle or sqlserver) to get the hostname, port, and database name. The formats of the URL are different.

pants
  • 192
  • 13
Mickel Lee
  • 473
  • 1
  • 5
  • 6
  • What do u mean by you want to parse a jdbc url. You can use regex. Can you give an example – Ank Feb 15 '12 at 02:25
  • 3
    jdbc:jtds:sqlserver://hostname:port/dbname or jdbc:jtds:sqlserver://hostname:port;databaseName=dbname or jdbc:oracle:thin:@hostname:port:dbname – Mickel Lee Feb 15 '12 at 02:41

4 Answers4

69

Start with something like this:

String url = "jdbc:derby://localhost:1527/netld;collation=TERRITORY_BASED:PRIMARY";
String cleanURI = url.substring(5);

URI uri = URI.create(cleanURI);
System.out.println(uri.getScheme());
System.out.println(uri.getHost());
System.out.println(uri.getPort());
System.out.println(uri.getPath());

Output from the above:

derby
localhost
1527
/netld;collation=TERRITORY_BASED:PRIMARY
brettw
  • 10,664
  • 2
  • 42
  • 59
  • thanks very much!i can get host,port easily in this way,but i have to parse the path to get the databasename – Mickel Lee Feb 15 '12 at 02:52
  • 12
    you will not be able to parse _some server_ out of jdbc:oracle:thin:@some.server:1521:XXX with that – Oleg Mikheev Jul 18 '12 at 17:24
  • 6
    Well, in general, the format of JDBC URL is DB-specific. So there is no universal way to parse it. – Alexei Osipov Oct 26 '15 at 16:59
  • Beware of hostnames with underscores in name. They are usual in docker compose environments or kubernates and are not handled correctly by this code (Ill post solution based on postgresql driver code later). – Lubo May 26 '23 at 07:15
6

That didn't work for me. I came up with these methods, based on the assumption that hostname and port are always joined together by a colon. That assumption holds for all the databases I have to deal with at work (Oracle, Vertica, MySQL, etc). But it probably don't work for something that doesn't reach out to a network port.

String url = null; // set elsewhere in the class
final public String regexForHostAndPort = "[.\\w]+:\\d+";
final public Pattern hostAndPortPattern = Pattern.compile(regexForHostAndPort);
public String getHostFromUrl() {
    Matcher matcher = hostAndPortPattern.matcher(url); 
    matcher.find();
    int start = matcher.start();
    int end = matcher.end();
    if(start >= 0 && end >= 0) {
        String hostAndPort = url.substring(start, end);
        String [] array = hostAndPort.split(":");
        if(array.length >= 2)
            return array[0];
    }
    throw new IllegalArgumentException("couldn't find pattern '" + regexForHostAndPort + "' in '" + url + "'");
}

public int getPortFromUrl() {
    Matcher matcher = hostAndPortPattern.matcher(url); 
    matcher.find();
    int start = matcher.start();
    int end = matcher.end();
    if(start >= 0 && end >= 0) {
        String hostAndPort = url.substring(start, end);
        String [] array = hostAndPort.split(":");
        if(array.length >= 2)
            return Integer.parseInt(array[1]);
    }
    throw new IllegalArgumentException("couldn't find pattern '" + regexForHostAndPort + "' in '" + url + "'");
}
1

I use this class in my projects. The use is really simple.

/**
 * Split di una url JDBC nei componenti.
 * Estrae i componenti di una uri JDBC del tipo: <br>
 * String url = "jdbc:derby://localhost:1527/netld;collation=TERRITORY_BASED:PRIMARY"; <br>
 * nelle rispettive variabili pubbliche.
 * @author Nicola De Nisco
 */
public class JdbcUrlSplitter
{
  public String driverName, host, port, database, params;

  public JdbcUrlSplitter(String jdbcUrl)
  {
    int pos, pos1, pos2;
    String connUri;

    if(jdbcUrl == null || !jdbcUrl.startsWith("jdbc:")
       || (pos1 = jdbcUrl.indexOf(':', 5)) == -1)
      throw new IllegalArgumentException("Invalid JDBC url.");

    driverName = jdbcUrl.substring(5, pos1);
    if((pos2 = jdbcUrl.indexOf(';', pos1)) == -1)
    {
      connUri = jdbcUrl.substring(pos1 + 1);
    }
    else
    {
      connUri = jdbcUrl.substring(pos1 + 1, pos2);
      params = jdbcUrl.substring(pos2 + 1);
    }

    if(connUri.startsWith("//"))
    {
      if((pos = connUri.indexOf('/', 2)) != -1)
      {
        host = connUri.substring(2, pos);
        database = connUri.substring(pos + 1);

        if((pos = host.indexOf(':')) != -1)
        {
          port = host.substring(pos + 1);
          host = host.substring(0, pos);
        }
      }
    }
    else
    {
      database = connUri;
    }
  }
}
1

Be aware that @brettw's answer can fail for some valid jdbc urls. If the host name contains an underscore uri getHost() returns null (see here) and getPost() returns -1.

To get around this I added a check for null host:

  String jdbcUrl = "jdbc:jtds:sqlserver://ABC_XYZ:1433/Database";
  String cleanURI = jdbcUrl.substring("jdbc:jtds:".length());

  URI uri = URI.create(cleanURI);
  String host = uri.getHost();
  int port = uri.getPort();

  if(host == null){
    String regex = ".*://(\\w*):(\\d++)/.*";
    Pattern p = Pattern.compile(regex);

    Matcher matcher = p.matcher(jdbcUrl);
    if(matcher.find()){
      host =  matcher.group(1);
      port =  Integer.valueOf(matcher.group(2));
    } else {
      // handle fail
    }
  }

  System.out.println("host = " + host);
  System.out.println("port = " + port);
JPC
  • 11
  • 6