1. ホーム
  2. java

[解決済み] 指定されたURLからドメイン名を取得する

2022-04-28 18:44:36

質問

URLが与えられたとき、ドメイン名('www'の部分を含まないこと)を抽出したいのですが。URLはhttp/httpsを含むことができます。以下は、私が書いたJavaコードです。うまくいっているように見えますが、もっと良い方法はないでしょうか。

public static String getDomainName(String url) throws MalformedURLException{
    if(!url.startsWith("http") && !url.startsWith("https")){
         url = "http://" + url;
    }        
    URL netUrl = new URL(url);
    String host = netUrl.getHost();
    if(host.startsWith("www")){
        host = host.substring("www".length()+1);
    }
    return host;
}

入力してください。 http://google.com/blah

出力:google.com

解決方法は?

URLをパースする場合は java.net.URI . java.net.URL は多くの問題を抱えている -- その equals メソッドはDNSルックアップを行うので、信頼できない入力で使用された場合、このメソッドを使用したコードはサービス拒否攻撃に対して脆弱になる可能性があることを意味します。

"ゴスロリさん -- なぜurlイコールが吸えるようにしたんですか?"。 は、そのような問題の一つを説明しています。 を使う習慣をつければいいのです。 java.net.URI の代わりに

public static String getDomainName(String url) throws URISyntaxException {
    URI uri = new URI(url);
    String domain = uri.getHost();
    return domain.startsWith("www.") ? domain.substring(4) : domain;
}

は、あなたが望むことを行う必要があります。


うまくいっているようですが、もっと良い方法はないでしょうか。それとも、失敗するようなエッジケースがあるのでしょうか。

あなたの書いたコードは、有効なURLのために失敗します。

  • httpfoo/bar -- で始まるパスコンポーネントを持つ相対 URL。 http .
  • HTTP://example.com/ -- プロトコルは大文字と小文字を区別しません。
  • //example.com/ -- プロトコル相対 URL にホスト
  • www/foo -- で始まるパスコンポーネントを持つ相対 URL。 www
  • wwwexample.com -- で始まらないドメイン名 www. で始まるが www .

階層型URLは複雑な文法を持っています。 RFC3986を注意深く読まずに独自のパーサーを作ろうとすると、おそらく間違うでしょう。 コアライブラリに組み込まれているものを使ってください。

という面倒な入力を本当に処理する必要がある場合、その入力に対応するために java.net.URI が拒否する場合は RFC 3986 付録Bをご覧ください。

付録B. 正規表現による URI 参照のパース

first-match-wins" アルゴリズムは、quot;greedy".と同じであるため、quot;first-match-wins" アルゴリズムを使用することができます。 と同じであるため、POSIX正規表現で使われている曖昧さ回避の方法と同じです。 を解析するために正規表現を使用するのは自然で当たり前のことです。 URI参照に含まれる5つの構成要素の可能性

次の行は、以下のような正規表現です。 URI参照を構成要素に分解しています。

  ^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?
   12            3  4          5       6  7        8 9

上の2行目の数字は読みやすくするためだけのものです。 各副表現の参照点(すなわち、それぞれの という括弧があります。)