URL 和 URI 区别

URL 和 URI 区别

本文我们讨论URL 和 URI 的主要区别,并通过示例说明这些差异。

URL 和 URI

直接差异来自其定义:

  • Uniform Resource Identifier (URI) − 对任何抽象或物理资源进行完整标识的字符序列。 Uniform
  • Resource Locator (URL) − 除了标识资源可用的位置之外,URI的一个子集描述了访问该资源的主要机制。

现在我们可以得出结论:每个URL都是一个URI,后面我们会看到情况并非如此。

语法

所有URI,不管其是否为URL,需遵循形式:

scheme:[//authority][/path][?query][#fragment]

每部分描述如下:

  • scheme − 对于 URL, 是访问资源的协议名称;对其他URI,是分配标识符的规范的名称
  • authority − 可选的组成用户授权信息部分,主机及端口(可选)
  • path − 用于在scheme和authority内标识资源
  • query − 与路径一起的附加数据用于标识资源。对于url是查询字符串
  • fragment − 资源特定部分的可选标识符

为了方便地识别特定的URI是否是URL,我们可以检查它的scheme。每个URL都必须从以下scheme开始:ftp、http、https、gopher、mailto、news、nntp、telnet、wais、file或prospero。如果不是以此开头,则不是URL。

现在我们已经了解了语法,让我们看一些示例。下面是uri列表,其中只有前三个是url:

    ftp://ftp.is.co.za/rfc/rfc1808.txt
    https://tools.ietf.org/html/rfc3986
    mailto:john@doe.com

    tel:+1-816-555-1212
    urn:oasis:names:docbook:dtd:xml:4.1
    urn:isbn:1234567890

URL 和 URI的java api区别

本节我们通过示例演示URL 和 URI的java api区别。

实例化

创建URL 和 URI实例很类似,两个类都提供了几个构造函数,接收大部分其组件,仅URI有接收全部组件的构造函数语法:

@Test
public void whenCreatingURIs_thenSameInfo() throws Exception {
    URI firstURI = new URI(
      "somescheme://theuser:thepassword@someauthority:80"
      + "/some/path?thequery#somefragment");

    URI secondURI = new URI(
      "somescheme", "theuser:thepassword", "someuthority", 80,
      "/some/path", "thequery", "somefragment");

    assertEquals(firstURI.getScheme(), secondURI.getScheme());
    assertEquals(firstURI.getPath(), secondURI.getPath());
}
@Test
public void whenCreatingURLs_thenSameInfo() throws Exception {
    URL firstURL = new URL(
      "http://theuser:thepassword@somehost:80"
      + "/path/to/file?thequery#somefragment");
    URL secondURL = new URL("http", "somehost", 80, "/path/to/file");

    assertEquals(firstURL.getHost(), secondURL.getHost());
    assertEquals(firstURL.getPath(), secondURL.getPath());
}

URI类提供了工具方法,用于创建新的实例,无需检查异常:

@Test
public void whenCreatingURI_thenCorrect() {
    URI uri = URI.create("urn:isbn:1234567890");

    assertNotNull(uri);
}

URL不提供这样方法。由于URL必须从前面提到的一个scheme开始,尝试用不同的scheme创建对象将导致异常:

@Test(expected = MalformedURLException.class)
public void whenCreatingURLs_thenException() throws Exception {
    URL theURL = new URL("otherprotocol://somehost/path/to/file");

    assertNotNull(theURL);
}

两个类都提供了其他的构造函数,读者可以查看相应文档

URI 和 URL 实例间转换

URI 和 URL 实例间转换很简单直接:

@Test
public void givenObjects_whenConverting_thenCorrect()
  throws MalformedURLException, URISyntaxException {
    String aURIString = "http://somehost:80/path?thequery";
    URI uri = new URI(aURIString);
    URL url = new URL(aURIString);

    URL toURL = uri.toURL();
    URI toURI = url.toURI();

    assertNotNull(url);
    assertNotNull(uri);
    assertEquals(toURL.toString(), toURI.toString());
}

然而,尝试转换非URL会抛出异常:

@Test(expected = MalformedURLException.class)
public void givenURI_whenConvertingToURL_thenException()
  throws MalformedURLException, URISyntaxException {
    URI uri = new URI("somescheme://someauthority/path?thequery");

    URL url = uri.toURL();

    assertNotNull(url);
}

打开远程连接

因为URL是有效的远程资源引用,java提供方法打开远程资源连接并获取其内容:

    @Test
    public void testOpenUrl() throws Exception {
        URL url = new URL("http://www.baidu.com");
        String contents = IOUtils.toString(url.openStream(),"utf-8");
        assertTrue(contents.contains("<!DOCTYPE html>"));
    }

总结

我们介绍了一些示例来说明Java中URI和URL之间的区别。分别说明了创建对象实例和转换象的差异。我们还展示了URL具有打开指向资源的远程连接的方法。

  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值