1. Обзор
В этой короткой статье мы рассмотрим основные различия между URI и URL-адресами и примерами реализации, чтобы подчеркнуть эти различия.
2. URL и URL-адрес
Разница между ними очевидна после того, как вы знаете их определения:
- Единый идентификатор ресурса (URI) − последовательность символов, позволяющая полностью идентифицировать любой абстрактный или физический ресурс
- Единый локатор ресурсов (URL) − подмножество URI, которое, помимо определения того, где доступен ресурс, описывает основной механизм доступа к нему
Теперь мы можем сделать вывод , что каждый URL-адрес является URI , но обратное неверно, как мы увидим позже.
2.1. Синтаксис
Каждый URI, независимо от того, является ли он URL-адресом или нет, следует определенной форме:
scheme:[//authority][/path][?query][#fragment]
Где каждая часть описывается следующим образом:
- схема − для URL-адресов-это имя протокола, используемого для доступа к ресурсу, для других URI-это имя, которое ссылается на спецификацию для назначения идентификаторов в этой схеме
- authority − необязательная часть, состоящая из информации аутентификации пользователя, хоста и дополнительного порта
- путь − он служит для идентификации ресурса в рамках его схемы и полномочий
- запрос − дополнительные данные, которые вместе с путем служат для идентификации ресурса. Для 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:[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()); }
Однако попытка преобразовать URL-адрес, не являющийся 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.baeldung.com"); String contents = IOUtils.toString(url.openStream()); assertTrue(contents.contains(" ")); }
4. Заключение
В этой краткой статье мы представили несколько примеров, демонстрирующих различия между URI и URL в Java.
Мы выделили различия при создании экземпляров обоих объектов и при преобразовании одного объекта в другой. Мы также показали, что URL имеет методы для открытия удаленного подключения к указанному ресурсу.
Как всегда, полный исходный код этой статьи можно найти на Github .