Java 从URL获取域名/主机名的最快方法是什么?

Java 从URL获取域名/主机名的最快方法是什么?,java,url,dns,Java,Url,Dns,我需要通过一个字符串url的大列表,并从中提取域名 例如: http://www.stackoverflow.com/questions将提取www.stackoverflow.com 我最初使用的是newurl(theUrlString).getHost(),但是URL对象初始化会给这个过程增加很多时间,似乎没有必要 是否有一种更快速的方法来提取可靠的主机名 谢谢 编辑:我错了,是的,上面的域名示例中将包含www。此外,这些URL可能是http或https如果您想处理https等,我建议您这样

我需要通过一个字符串url的大列表,并从中提取域名

例如:

http://www.stackoverflow.com/questions将提取www.stackoverflow.com

我最初使用的是
newurl(theUrlString).getHost()
,但是URL对象初始化会给这个过程增加很多时间,似乎没有必要

是否有一种更快速的方法来提取可靠的主机名

谢谢


编辑:我错了,是的,上面的域名示例中将包含www。此外,这些URL可能是http或https

如果您想处理
https
等,我建议您这样做:

int slashslash = url.indexOf("//") + 2;
domain = url.substring(slashslash, url.indexOf('/', slashslash));
请注意,这包括
www
部分(就像
URL.getHost()
一样),它实际上是域名的一部分

通过评论请求编辑

以下是两种可能有用的方法:

/**
 * Will take a url such as http://www.stackoverflow.com and return www.stackoverflow.com
 * 
 * @param url
 * @return
 */
public static String getHost(String url){
    if(url == null || url.length() == 0)
        return "";

    int doubleslash = url.indexOf("//");
    if(doubleslash == -1)
        doubleslash = 0;
    else
        doubleslash += 2;

    int end = url.indexOf('/', doubleslash);
    end = end >= 0 ? end : url.length();

    int port = url.indexOf(':', doubleslash);
    end = (port > 0 && port < end) ? port : end;

    return url.substring(doubleslash, end);
}


/**  Based on : http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.3.3_r1/android/webkit/CookieManager.java#CookieManager.getBaseDomain%28java.lang.String%29
 * Get the base domain for a given host or url. E.g. mail.google.com will return google.com
 * @param host 
 * @return 
 */
public static String getBaseDomain(String url) {
    String host = getHost(url);

    int startIndex = 0;
    int nextIndex = host.indexOf('.');
    int lastIndex = host.lastIndexOf('.');
    while (nextIndex < lastIndex) {
        startIndex = nextIndex + 1;
        nextIndex = host.indexOf('.', startIndex);
    }
    if (startIndex > 0) {
        return host.substring(startIndex);
    } else {
        return host;
    }
}
/**
*将采用url,例如http://www.stackoverflow.com 并返回www.stackoverflow.com
* 
*@param-url
*@返回
*/
公共静态字符串getHost(字符串url){
if(url==null | | url.length()==0)
返回“”;
int doubleslash=url.indexOf(“/”);
如果(双斜杠==-1)
双斜杠=0;
其他的
双斜杠+=2;
int end=url.indexOf(“/”,双斜杠);
end=end>=0?end:url.length();
int port=url.indexOf(“:”,双斜杠);
end=(端口>0&&port0){
返回host.substring(startIndex);
}否则{
返回主机;
}
}

你能写一个regexp吗?http://总是相同的,然后匹配所有内容,直到得到第一个“/”。

假设它们都是格式良好的URL,但您不知道它们是否为http://、https://,等等


int start = theUrlString.indexOf('/');
int start = theUrlString.indexOf('/', start+1);
int end = theUrlString.indexOf('/', start+1);
String domain = theUrlString.subString(start, end);

您可以尝试使用正则表达式

下面是一个关于在Java中使用正则表达式提取域名的问题:


在实现“快速”取消链接URL时,您需要相当小心。URL中存在很多潜在的变化,可能会导致“快速”方法失败。例如:

  • 方案(协议)部分可以用大写字母和小写字母的任意组合书写;e、 g.“http”、“http”和“http”是等效的

  • 授权部分可以选择性地包括用户名和/或端口号,如“”所示

  • 由于DNS不区分大小写,URL的主机名部分也(实际上)不区分大小写

  • 在URL的scheme或authority组件中对未保留字符进行编码是合法的(尽管非常不规则)。在匹配(或剥离)方案或解释主机名时,需要考虑这一点。具有%编码字符的主机名定义为等同于解码了%编码序列的主机名

现在,如果您完全控制了生成要剥离的URL的过程,那么您可能可以忽略这些细节。但是如果他们是从文档或网页中获取的,或者是由人类输入的,那么你最好考虑一下如果你的代码遇到一个“不寻常”的URL会发生什么。

如果您关心的是构造URL对象所需的时间,则考虑使用URI对象。URI对象不会尝试对主机名部分进行DNS查找。我编写了一个方法(见下文),该方法提取url的域名,并使用简单的字符串匹配。它实际做的是提取第一个

“:/”
(或者索引
0
,如果没有
“:/”
)和第一个后续
“/”
(或者索引
字符串.length()
,如果没有后续
“/”
)。剩余的前面的
“www()*.”
位被截断。我肯定会有这样的情况,这将是不够好,但它应该在大多数情况下足够好

我读到
java.net.URI
类可以做到这一点(并且比
java.net.URL
类更可取),但是我遇到了
URI
类的问题。值得注意的是,
URI.getHost()
如果url不包括方案,即
“http(s)”
位,则会给出一个空值

/**
 * Extracts the domain name from {@code url}
 * by means of String manipulation
 * rather than using the {@link URI} or {@link URL} class.
 *
 * @param url is non-null.
 * @return the domain name within {@code url}.
 */
public String getUrlDomainName(String url) {
  String domainName = new String(url);

  int index = domainName.indexOf("://");

  if (index != -1) {
    // keep everything after the "://"
    domainName = domainName.substring(index + 3);
  }

  index = domainName.indexOf('/');

  if (index != -1) {
    // keep everything before the '/'
    domainName = domainName.substring(0, index);
  }

  // check for and remove a preceding 'www'
  // followed by any sequence of characters (non-greedy)
  // followed by a '.'
  // from the beginning of the string
  domainName = domainName.replaceFirst("^www.*?\\.", "");

  return domainName;
}

在该类中尝试方法:getDomainFromUrl()

package com.visc.mobilesecurity.childrencare.utils;

import android.content.Context;

import com.visc.mobilesecurity.antitheft.backwardcompatibility.FroyoSupport;
import com.visc.mobilesecurity.antitheft.util.AntiTheftUtils;
import com.visc.mobilesecurity.constant.Key;
import com.visc.mobilesecurity.util.Prefs;

import org.json.JSONObject;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;

/**
 * Created by thongnv12 on 3/9/2018.
 */

public class ChildcareUtils {

    public static final String[] NATION_DOMAIN = {"af", "ax", "al", "dz", "as", "ad", "ao", "ai", "aq", "ag", "ar", "am", "aw", "ac", "au", "at", "az", "bs", "bh", "bd", "bb", "eus",
            "by", "be", "bz", "bj", "bm", "bt", "bo", "bq", "ba", "bw", "bv", "br", "io", "vg", "bn", "bg", "bf", "mm", "bi", "kh", "cm", "ca", "cv", "cat", "ky", "cf", "td", "cl",
            "cn", "cx", "cc", "co", "km", "cd", "cg", "ck", "cr", "ci", "hr", "cu", "cw", "cy", "cz", "dk", "dj", "dm", "do", "tl", "ec", "eg", "sv", "gq", "er", "ee", "et", "eu",
            "fk", "fo", "fm", "fj", "fi", "fr", "gf", "pf", "tf", "ga", "gal", "gm", "ps", "ge", "de", "gh", "gi", "gr", "gl", "gd", "gp", "gu", "gt", "gg", "gn", "gw", "gy", "ht",
            "hm", "hn", "hk", "hu", "is", "in", "id", "ir", "iq", "ie", "im", "il", "it", "jm", "jp", "je", "jo", "kz", "ke", "ki", "kw", "kg", "la", "lv", "lb", "ls", "lr", "ly",
            "li", "lt", "lu", "mo", "mk", "mg", "mw", "my", "mv", "ml", "mt", "mh", "mq", "mr", "mu", "yt", "mx", "md", "mc", "mn", "me", "ms", "ma", "mz", "mm", "na", "nr", "np",
            "nl", "nc", "nz", "ni", "ne", "ng", "nu", "nf", "kp", "mp", "no", "om", "pk", "pw", "ps", "pa", "pg", "py", "pe", "ph", "pn", "pl", "pt", "pr", "qa", "ro", "ru", "rw",
            "re", "bq", "bl", "sh", "kn", "lc", "mf", "fr", "pm", "vc", "ws", "sm", "st", "sa", "sn", "rs", "sc", "sl", "sg", "bq", "sx", "sk", "si", "sb", "so", "so", "za", "gs",
            "kr", "ss", "es", "lk", "sd", "sr", "sj", "sz", "se", "ch", "sy", "tw", "tj", "tz", "th", "tg", "tk", "to", "tt", "tn", "tr", "tm", "tc", "tv", "ug", "ua", "ae", "uk",
            "us", "vi", "uy", "uz", "vu", "va", "ve", "vn", "wf", "eh", "zm", "zw"};


    public static boolean isInNationString(String str) {
        for (int index = 0; index < NATION_DOMAIN.length; index++) {
            if (NATION_DOMAIN[index].equals(str)) {
                return true;
            }
        }
        return false;
    }


    public static String getDomainFromUrl(String urlStr) {
        try {
            String result = null;
//            URL url = new URL(urlStr);
//            result = url.getHost();
//            return result;
//
            // for test
            // check dau cach
            if (urlStr.contains(" ")) {
                return null;
            }
            // replace
            urlStr = urlStr.replace("https://", "");
            urlStr = urlStr.replace("http://", "");
            urlStr = urlStr.replace("www.", "");
            //
            String[] splitStr = urlStr.split("/");

            String domainFull = splitStr[0];

            String[] splitDot = domainFull.split("\\.");

            if (splitDot.length < 2) {
                return null;
            }

            String nationStr = splitDot[splitDot.length - 1];

            if (isInNationString(nationStr)) {
                if (splitDot.length < 4) {
                    result = domainFull;
                } else {
                    StringBuilder strResult = new StringBuilder();
                    int lengthDot = splitDot.length;
                    strResult.append(splitDot[lengthDot - 3]).append(".");
                    strResult.append(splitDot[lengthDot - 2]).append(".");
                    strResult.append(splitDot[lengthDot - 1]);
                    result = strResult.toString();
                }

            } else {
                if (splitDot.length < 3) {
                    result = domainFull;
                } else {
                    StringBuilder strResult = new StringBuilder();
                    int lengthDot = splitDot.length;
                    strResult.append(splitDot[lengthDot - 2]).append(".");
                    strResult.append(splitDot[lengthDot - 1]);
                    result = strResult.toString();
                }
            }
            return result;
        } catch (Exception ex) {
            ex.printStackTrace();
            return null;
        }

    }
}
package com.visc.mobilesecurity.childrencare.utils;
导入android.content.Context;
导入com.visc.mobilesesecurity.antitheft.backwardcompatibility.FroyoSupport;
进口com.visc.mobilesesecurity.antitheft.util.AntiTheftUtils;
导入com.visc.mobilesesecurity.constant.Key;
导入com.visc.mobilesesecurity.util.Prefs;
导入org.json.JSONObject;
导入java.io.File;
导入java.io.FileOutputStream;
导入java.io.InputStream;
/**
*由thongnv12于2018年3月9日创建。
*/
公营儿童保育院{
公共静态最终字符串[]国家域={“af”、“ax”、“al”、“dz”、“as”、“ad”、“ao”、“ai”、“aq”、“ag”、“ar”、“am”、“aw”、“ac”、“au”、“at”、“az”、“bs”、“bh”、“bd”、“bb”、“eus”,
“by”、“be”、“bz”、“bj”、“bm”、“bt”、“bo”、“bq”、“ba”、“bw”、“bv”、“br”、“io”、“vg”、“bn”、“bg”、“bf”、“mm”、“bi”、“kh”、“cm”、“ca”、“cv”、“cat”、“ky”、“cf”、“td”、“cl”,
private String getHostName(String hostname) {
    // to provide faultproof result, check if not null then return only hostname, without www.
    if (hostname != null) {
        return hostname.startsWith("www.") ? hostname.substring(4) : getHostNameDFExt(hostname);
    }
    return hostname;
}

private String getHostNameDFExt(String hostname) {

    int substringIndex = 0;
    for (char character : hostname.toCharArray()) {
        substringIndex++;
        if (character == '.') {
            break;
        }
    }

    return hostname.substring(substringIndex);

}
URL url = new URL("https://www.facebook.com/");
String hostname = getHostName(ur.getHost());

Toast.makeText(this, hostname, Toast.LENGTH_SHORT).show();