这篇文章只关注一个URL字符串是否是合法的,并不讨论这个URL对应的资源是否能够访问(有效)。
如果想看Java代码实现的部分,建议直接看文章末尾。
先粗略研究一下概念,关于URI和URL的关系,维基百科上有比较好的介绍:[传送门]
其实看起来还是没太清楚,于是翻了RFC3986[传送门],找到了下面这个图:
The following are two example URIs and their component parts: foo://example.com:8042/over/there?name=ferret#nose \_/ \______________/\_________/ \_________/ \__/ | | | | | scheme authority path query fragment | _____________________|__ / \ / \ urn:example:animal:ferret:nose
上面的图给出了两个URI的例子。第一个例子是最常见的,大家每天都在用,这个博客的网址就属于这种。
http://blog.csdn.net/godric42/
其中http是scheme,更常用的说法是协议;blog.csdn.net是authority,也就是主机;/godric42/是path。
第二个例子对于使用P2P软件下载东西的同学也不陌生,可以去Google一下“磁力链接”。
有了上面的基本概念,我们约定:后文提到的“网址”,其实是在说URI。
下面用一个特例来看一下Java中URI类和URL类的区别。
String urlStr = "http://#/?a=b";
URI uri = null;
try {
uri = new URI(urlStr);
} catch (URISyntaxException e) {
e.printStackTrace();
}
System.out.println(uri.getHost()); //null
URL url = null;
try {
url = new URL(urlStr);
} catch (MalformedURLException e) {
e.printStackTrace();
}
System.out.println(url.getHost()); //#
我们看到,使用URI和URL都能成功创建对象,但调用URI的getHost方法得到的是null,而调用URL的getHost方法输出是#。
使用URI这个类来判断一个网址的合法性是比较合适的,具体步骤如下:
- 先新建一个URI对象;
- 如果创建失败,则认为该URL不合法;
- 如果创建成功,再检查host是否为null;
- 如果host不为null,在检查协议是否是应用中能够处理的。
最终的代码如下。
public static boolean isValidUrl(String urlString){
URI uri = null;
try {
uri = new URI(urlString);
} catch (URISyntaxException e) {
e.printStackTrace();
return false;
}
if(uri.getHost() == null){
return false;
}
if(uri.getScheme().equalsIgnoreCase("http") || uri.getScheme().equalsIgnoreCase("https")){
return true;
}
return false;
}
结论:使用URI类来判断地址的合法性比较方便。
思考:既然URL是URI的子集,那么Java的URL类和URI类为什么会返回不同的host结果呢?看来需要研究一下源码。