簡體   English   中英

如何解析JDBC url以獲取主機名,端口等?

[英]How to parse a JDBC url to get hostname,port etc?

如何解析JDBC URL(oracle或sqlserver)以獲取主機名,端口和數據庫名稱。 URL的格式不同。

從這樣的事情開始:

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());

以上輸出:

derby
localhost
1527
/netld;collation=TERRITORY_BASED:PRIMARY

這對我不起作用。 我提出了這些方法,基於主機名和端口始終通過冒號連接在一起的假設。 這個假設適用於我在工作中處理的所有數據庫(Oracle,Vertica,MySQL等)。 但它可能不適用於無法接觸到網絡端口的東西。

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 + "'");
}

我在我的項目中使用這個類。 用法非常簡單。

/**
 * 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;
    }
  }
}

請注意,對於某些有效的jdbc網址,@ brettw的答案可能會失敗。 如果主機名包含下划線uri,則getHost()返回null(請參閱此處 ),getPost()返回-1。

為了解決這個問題,我添加了對空主機的檢查:

  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);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM