Разница между URL и URI

Разница между URL и URI

1. обзор

В этой короткой статье мы рассмотрим основные различия между URI и URL и реализуем примеры, чтобы выделить эти различия.

2. URI и URL

Разница между ними очевидна после понимания их определений:

  • Uniform Resource Identifier (URI) - последовательность символов, позволяющая полностью идентифицировать любой абстрактный или физический ресурс

  • Uniform Resource Locator (URL) - подмножество URI, которое, помимо определения того, где доступен ресурс, описывает основной механизм доступа к нему

Now we can conclude that every URL is a URI, но обратное неверно, как мы увидим позже.

2.1. Синтаксис

Каждый URI, независимо от того, является он URL-адресом или нет, следует определенной форме:

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

Где каждая часть описана следующим образом:

  • scheme - для URL-адресов - это имя протокола, используемого для доступа к ресурсу, для других URI - это имя, которое относится к спецификации для присвоения идентификаторов в этой схеме

  • authority - необязательная часть, состоящая из информации аутентификации пользователя, хоста и необязательного порта

  • path - служит для идентификации ресурса в рамках егоscheme иauthority

  • query - дополнительные данные, которые вместе сpath, служат для идентификации ресурса. Для URL это строка запроса

  • fragment - необязательный идентификатор определенной части ресурса

To easily identify if a particular URI is also a URL, we can check its scheme. Каждый URL-адрес должен начинаться с любой из этих схем: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:[email protected]

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

3. Различия в URI и URL Java API

В этом разделе мы продемонстрируем на примерах основные различия между классамиURI иURL, предоставляемыми Java.

3.1. Конкретизация

Создание экземпляровURI иURL очень похоже, оба класса предоставляют несколько конструкторов, которые принимают большую часть его частей, однако только классURI имеет конструктор для определения всех частей синтаксиса:

@Test
public void whenCreatingURIs_thenSameInfo() throws Exception {
    URI firstURI = new URI(
      "somescheme://theuser:[email protected]: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:[email protected]: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 должен начинаться с одной из ранее упомянутых схем, попытка создать объект с другой приведет к исключению:

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

    assertNotNull(theURL);
}

В обоих классах есть другие конструкторы, чтобы узнать их все, обратитесь к документацииURI иURL.

3.2. Преобразование между экземплярами 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());
}

Тем не менее, попытка преобразовать URI не-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);
}

3.3. Открытие удаленного подключения

Поскольку URL является допустимой ссылкой на удаленный ресурс, Java предоставляет методы для открытия соединения с этим ресурсом и получения его содержимого:

@Test
public void givenURL_whenGettingContents_thenCorrect()
  throws MalformedURLException, IOException {
    URL url = new URL("http://courses.example.com");

    String contents = IOUtils.toString(url.openStream());

    assertTrue(contents.contains(""));
}

4. Заключение

В этой быстрой статье мы представили несколько примеров, чтобы продемонстрировать различия междуURI иURL в Java.

Мы выделили различия при создании экземпляров обоих объектов и при преобразовании одного объекта в другой. Мы также показали, чтоURL имеет методы для открытия удаленного соединения с указанным ресурсом.

Как всегда, полный исходный код этой статьи можно найти наover on Github.