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);
}
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.