在Java中从URL获取域名,最标准且可靠的方法是使用java.net.URL类的getHost()方法,该方法返回主机名(含子域名),但需处理异常和端口问题;若需提取注册域名(如example.com),推荐使用Guava的InternetDomainName或正则表达式,具体选择取决于业务场景。

基于java.net.URL的标准获取方式
1 基础用法与异常处理
解析URL字符串时,最常见的方法是创建URL对象并调用getHost(),这是最直接的java url 获取域名 方法。
URL url = new URL("https://www.example.com:8080/path?query=1");
String host = url.getHost(); // 返回 "www.example.com"
关键点:
new URL()会抛出MalformedURLException,必须捕获或抛出。- 若URL缺少协议(如
www.example.com),会直接抛出异常,因此需先补充http://前缀。 getHost()返回的是小写主机名,不包含端口、协议和路径。
2 处理端口与默认端口
当需要同时获取域名和端口时,即java 获取域名 和 端口,可使用getHost()和getPort()组合。getPort()在未显式指定端口时返回-1,需根据协议设置默认端口(HTTP 80,HTTPS 443),示例工具方法:
public static String getDomainWithPort(String urlString) throws MalformedURLException {
URL url = new URL(urlString);
String host = url.getHost();
int port = url.getPort();
return port == -1 ? host : host + ":" + port;
}
注意:此方法仅处理绝对URL,对于相对URL需先拼接base URL。
3 获取完整域名与路径
URL类还提供getProtocol()、getPath()、getQuery()等方法,可解析URL的全部组成部分,但聚焦域名时,getHost()已满足大部分需求,对于java 获取域名 工具类的封装,可结合这些方法实现统一入口。
提取主域名(注册域名)的多种方案
实际业务中常需从URL中提取“注册域名”(去掉子域名,如www.、blog.),仅保留example.com。getHost()返回完整主机名,无法直接剥离子域名,因此需要借助其他方案。
1 使用Guava的InternetDomainName
Google Guava库的InternetDomainName类,专门用于域名处理,其topPrivateDomain()方法基于Public Suffix List(PSL)返回注册域名,是java 从url中提取域名 不带www的首选方案。
示例:
import com.google.common.net.InternetDomainName; String host = "www.example.co.uk"; InternetDomainName domainName = InternetDomainName.from(host); String registrableDomain = domainName.topPrivateDomain().toString(); // 返回 "example.co.uk"
优势:

- 准确处理多部分TLD(如
co.uk、com.au)。 - 自动跟随PSL更新,无需手动维护规则。
- 提供
isUnderPublicSuffix()、parent()等方法,适合复杂域名分析。
2 使用正则表达式提取
对于简单且已知格式的场景,可使用java 获取域名 正则表达式,但正则无法处理公共后缀列表,易出错,仅推荐用于内部可控环境。
常用正则:
String regex = "(?:https?://)?(?:www\.)?([^./]+\.[^./]+)(?:/.)?";
Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(url);
if (matcher.find()) {
String domain = matcher.group(1); // 如 "example.com"
}
局限性:对co.uk、org.cn等域名会误判,需结合白名单。
3 方法对比与性能
| 方法 | 准确性 | 性能 | 依赖 | 推荐场景 |
|---|---|---|---|---|
URL.getHost() |
中(含子域) | 极高 | 无 | 获取完整主机名 |
Guava InternetDomainName |
高(支持PSL) | 高 | 需引入Guava | 提取注册域名 |
| 正则表达式 | 低(需定制) | 高 | 无 | 简单且已知格式 |
实战建议:若项目已引入Guava,直接使用InternetDomainName;否则,可权衡准确性与依赖成本选择正则或URL.getHost()。
国际化域名(IDN)与编码处理
当URL包含非ASCII字符(如中文域名)时,URL类会自动进行Punycode编码。getHost()返回ASCII编码后的字符串(如xn--...),若需显示原始字符,需使用java.net.IDN.toUnicode()转换。
示例:
URL url = new URL("http://例子.测试");
String asciiHost = url.getHost(); // "xn--fsqu00a.xn--0zwm56d"
String unicodeHost = java.net.IDN.toUnicode(asciiHost); // "例子.测试"
注意:IDN.toUnicode()可能抛出IllegalArgumentException,需处理异常,对于java 从url中提取域名场景,若输出要求可读,务必进行IDN转换。
实战中的坑点与最佳实践
1 缺少协议时的处理
URL类要求协议必须存在,否则抛出异常,推荐先使用URI类进行宽松解析,再转为URL,或直接使用URI.getHost():
URI uri = new URI("//www.example.com/path"); // 相对URI
String host = uri.getHost(); // 返回 "www.example.com"
注意:URI对格式更宽容,但需确保调用parseServerAuthority()来验证主机合法性。
2 相对URL与绝对URL
URL类只能解析绝对URL,处理相对URL时,需先基于base URL构造:

URL base = new URL("https://example.com/base/");
URL relative = new URL(base, "../page.html");
String host = relative.getHost(); // 从base继承
在java url 获取域名 方法的封装中,应明确入参要求,避免相对URL引发异常。
3 缓存与多线程安全
URL对象一旦创建,其getHost()返回的字符串是固定的,线程安全,但URL的DNS解析发生在openConnection()或getContent()等网络操作时,getHost()本身不涉及网络,因此无性能隐患,可放心在多线程环境下使用。
从URL获取域名是Java开发中的高频需求。基础场景直接使用java.net.URL.getHost(),简单高效;注册域名提取推荐Guava的InternetDomainName,准确性经过PSL验证;国际化域名需注意IDN编码转换,根据业务场景选择合适方案,即可满足java url 获取域名的绝大多数需求,整体而言,URL.getHost()配合Guava的topPrivateDomain()是当前最稳健的实践组合。
常见问题解答
Java中如何从URL字符串中提取域名?
最直接的方法是使用URL.getHost(),若需获取注册域名(不带子域名),第一步先用getHost()获取主机名,第二步用Guava的InternetDomainName.from().topPrivateDomain()提取,两步配合即可覆盖常见场景。
如何获取不带www的域名?
使用Guava的InternetDomainName.from(host).topPrivateDomain(),该方法自动剥离所有子域名,返回注册域名,若需仅去掉www.而保留其他子域名,可使用正则或字符串替换,但准确性不如Guava。
如何判断两个URL是否同域(忽略子域名和协议)?
提取注册域名后比较。InternetDomainName.from(url1.getHost()).topPrivateDomain().equals(InternetDomainName.from(url2.getHost()).topPrivateDomain()),这种方法可忽略子域名差异,适用于单点登录、跨域校验等场景。
如果你有更具体的java 获取域名 工具类封装需求,欢迎在评论区交流。
参考文献
- Oracle Corporation. Java 21 API Specification – java.net.URL, java.net.IDN. 2026. (文档持续更新,2026年仍为LTS版本核心参考)
- Google Guava Team. Guava 33.0 API – com.google.common.net.InternetDomainName. 2026. (基于Public Suffix List的域名解析实现)
- Stack Overflow. How to extract domain name from URL in Java?. 2026. (高赞回答汇总了多种方案及性能对比)
- Mozilla Foundation. Public Suffix List. 2026. (Guava和大多数浏览器域名解析的底层数据源)
图片来源于AI模型,如侵权请联系管理员。作者:酷小编,如若转载,请注明出处:https://www.kufanyun.com/ask/630271.html


评论列表(2条)
这篇文章的内容非常有价值,我从中学习到了很多新的知识和观点。作者的写作风格简洁明了,却又不失深度,让人读起来很舒服。特别是获取域名部分,给了我很多新的思路。感谢分享这么好的内容!
这篇文章的内容非常有价值,我从中学习到了很多新的知识和观点。作者的写作风格简洁明了,却又不失深度,让人读起来很舒服。特别是获取域名部分,给了我很多新的思路。感谢分享这么好的内容!