Diferença entre URL e URI

Diferença entre URL e URI

1. Visão geral

Neste breve artigo, daremos uma olhada nas principais diferenças entre URIs e URLs e implementaremos exemplos para destacar essas diferenças.

2. URI e URL

A diferença entre eles é simples depois de conhecer suas definições:

  • Uniform Resource Identifier (URI) - uma sequência de caracteres que permite a identificação completa de qualquer recurso abstrato ou físico

  • Uniform Resource Locator (URL) - um subconjunto de URI que, além de identificar onde um recurso está disponível, descreve o mecanismo principal para acessá-lo

Now we can conclude that every URL is a URI, mas o oposto não é verdade, como veremos mais tarde.

2.1. Sintaxe

Cada URI, independentemente de ser um URL ou não, segue uma forma particular:

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

Onde cada parte é descrita da seguinte maneira:

  • scheme - para URLs, é o nome do protocolo usado para acessar o recurso, para outros URIs, é um nome que se refere a uma especificação para atribuir identificadores dentro desse esquema

  • authority - uma parte opcional composta de informações de autenticação do usuário, um host e uma porta opcional

  • path - serve para identificar um recurso dentro do escopo de seusschemeeauthority

  • query - dados adicionais que, junto compath,, servem para identificar um recurso. Para URLs, esta é a string de consulta

  • fragment - um identificador opcional para uma parte específica do recurso

To easily identify if a particular URI is also a URL, we can check its scheme. Cada URL deve começar com qualquer um destes esquemas:ftp,http,https,gopher,mailto,news,nntp,telnet,wais,file ouprospero. Se não começar com ele, então não é um URL.

Agora que conhecemos a sintaxe, vamos ver alguns exemplos. Aqui está uma lista de URIs, onde apenas os três primeiros são URLs:

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 e diferenças de API Java de URL

Nesta seção, vamos demonstrar com exemplos as principais diferenças entre as classesURIeURL fornecidas por Java.

3.1. Instanciação

A criação de instânciasURIeURL é muito semelhante, ambas as classes fornecem vários construtores que aceitam a maioria de suas partes, no entanto, apenas a classeURI tem um construtor para especificar todas as partes da sintaxe:

@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());
}

A classeURI também fornece um método utilitário para criar uma nova instância que não lança uma exceção verificada:

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

    assertNotNull(uri);
}

A classeURL não fornece esse método.

Como uma URL precisa começar com um dos esquemas mencionados anteriormente, tentar criar um objeto com outro diferente resultará em uma exceção:

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

    assertNotNull(theURL);
}

Existem outros construtores em ambas as classes, para descobrir todos eles, consulte a documentaçãoURI eURL.

3.2. Conversão entre instâncias de URI e URL

A conversão entre URI e URL é bastante direta:

@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());
}

No entanto, a tentativa de converter um URI sem URL resulta em uma exceção:

@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. Abrindo uma conexão remota

Como uma URL é uma referência válida para um recurso remoto, Java fornece métodos para abrir uma conexão com esse recurso e obter seu conteúdo:

@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. Conclusão

Neste artigo rápido, apresentamos alguns exemplos para demonstrar as diferenças entreURIeURL em Java.

Destacamos as diferenças ao criar instâncias de ambos os objetos e ao converter um objeto no outro. Também mostramos que aURL possui métodos para abrir uma conexão remota com o recurso apontado.

Como sempre, o código-fonte completo deste artigo pode ser encontradoover on Github.