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 .