Перейти к основному содержимому

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

· 4 мин. чтения

1. Обзор

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

2. URI и URL

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

  • Унифицированный идентификатор ресурса (URI) — последовательность символов, которая позволяет полностью идентифицировать любой абстрактный или физический ресурс.
  • Унифицированный указатель ресурса (URL) — подмножество URI, которое, помимо определения того, где доступен ресурс, описывает основной механизм доступа к нему.

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

2.1. Синтаксис

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

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

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

  • схема — для URL-адресов — это имя протокола, используемого для доступа к ресурсу, для других URI — это имя, которое относится к спецификации для назначения идентификаторов в этой схеме.
  • полномочия — необязательная часть, состоящая из информации об аутентификации пользователя, хоста и необязательного порта.
  • путь — служит для идентификации ресурса в рамках его схемы и полномочий
  • запрос — дополнительные данные, которые вместе с путем служат для идентификации ресурса. Для URL это строка запроса
  • фрагмент — необязательный идентификатор определенной части ресурса

Чтобы легко определить, является ли конкретный URI также URL-адресом, мы можем проверить его схему . Каждый 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:john@doe.com

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: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-адрес должен начинаться с одной из ранее упомянутых схем, попытка создать объект с другой схемой приведет к исключению:

@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.foreach.com");

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

assertTrue(contents.contains("<!DOCTYPE html>"));
}

4. Вывод

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

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

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