从给定的网址获取域名

2022-08-31 07:22:57

给定一个URL,我想提取域名(它不应该包括“www”部分)。网址可以包含 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


答案 1

如果要解析 URL,请使用 java.net.URI。 有很多问题 - 它的方法进行DNS查找,这意味着使用它的代码在与不受信任的输入一起使用时容易受到拒绝服务攻击。java.net.URLequals

“高斯林先生——你为什么把网址等于烂?”解释了一个这样的问题。只要养成使用习惯即可。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-- 具有以 开头的路径组件的相对 URLwww
  • wwwexample.com-- 不以 开头但以 开头的域名。www.www

分层 URL 具有复杂的语法。如果您尝试在不仔细阅读RFC 3986的情况下滚动自己的解析器,则可能会出错。只需使用核心库中内置的那个。

如果您确实需要处理拒绝的混乱输入,请参阅 RFC 3986 附录 B:java.net.URI

附录 B. 使用正则表达式分析 URI 引用

由于“首次匹配获胜”算法与 POSIX 正则表达式使用的“贪婪”消歧义方法相同,因此使用正则表达式来解析 URI 引用的潜在五个组件是自然而常见的。

以下行是用于将格式正确的 URI 引用分解为其组件的正则表达式。

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

上面第二行中的数字只是为了提高可读性;它们指示每个子表达式的参考点(即,每个成对的括号)。


答案 2
import java.net.*;
import java.io.*;

public class ParseURL {
  public static void main(String[] args) throws Exception {

    URL aURL = new URL("http://example.com:80/docs/books/tutorial"
                       + "/index.html?name=networking#DOWNLOADING");

    System.out.println("protocol = " + aURL.getProtocol()); //http
    System.out.println("authority = " + aURL.getAuthority()); //example.com:80
    System.out.println("host = " + aURL.getHost()); //example.com
    System.out.println("port = " + aURL.getPort()); //80
    System.out.println("path = " + aURL.getPath()); //  /docs/books/tutorial/index.html
    System.out.println("query = " + aURL.getQuery()); //name=networking
    System.out.println("filename = " + aURL.getFile()); ///docs/books/tutorial/index.html?name=networking
    System.out.println("ref = " + aURL.getRef()); //DOWNLOADING
  }
}

阅读更多