如何检查URL的合法性?

来源:互联网 发布:中国程序员数量不够 编辑:程序博客网 时间:2024/04/26 06:12

这篇文章只关注一个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这个类来判断一个网址的合法性是比较合适的,具体步骤如下:

  1. 先新建一个URI对象;
  2. 如果创建失败,则认为该URL不合法;
  3. 如果创建成功,再检查host是否为null;
  4. 如果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结果呢?看来需要研究一下源码。


0 0