Digamos que eu tenho um URL.
http://example.com/query?q=
e eu tenho uma consulta introduzida pelo usuário, como por exemplo:
palavra aleatória £500 banco $
Eu quero que o resultado seja um URL devidamente codificado:
http://example.com/query?q=random%20word%20%A3500%20bank%20%24
Qual'é a melhor maneira de conseguir isto? Eu tentei URLEncoder
e criar objetos URI/URL, mas nenhum deles saiu muito bem.
TURLEncoder` deve ser o caminho a seguir. Você só precisa ter em mente para codificar somente o nome e/ou valor do parâmetro individual da query string, não a URL inteira, com certeza não o caractere separador do parâmetro da query string &
nem o caractere separador do valor do nome do parâmetro =
.
String q = "random word £500 bank $";
String url = "http://example.com/query?q=" + URLEncoder.encode(q, "UTF-8");
Note que os espaços nos parâmetros de consulta são representados por +
, e não por %20
, o que é legitimamente válido. O %20
é normalmente utilizado para representar espaços no próprio URI (a parte antes do caractere separador da string URI ?``), não na string da consulta (a parte depois de
?``).
Note também que existem dois métodos encode()
. Um sem argumento charset e outro com. O sem argumento de charset é depreciado. Nunca o utilize e sempre especifique o argumento charset. O javadoc recomenda mesmo explicitamente a utilização da codificação UTF-8, conforme mandado por RFC3986 e W3C.
Todos os outros caracteres são inseguros e são primeiro convertidos em um ou mais bytes usando algum esquema de codificação. Depois cada byte é representado pela cadeia de 3 caracteres "%xy" onde xy é a representação hexadecimal de dois dígitos do byte. **O esquema de codificação recomendado para usar é UTF-8***. Entretanto, por razões de compatibilidade, se uma codificação não for especificada, então a codificação padrão da plataforma é usada.
Eu não utilizaria o URLEncoder
. Além de ser chamado incorretamente (o URLEncoder
não tem nada a ver com URLs), ineficiente (ele utiliza um StringBuffer
ao invés de Builder e faz algumas outras coisas que são lentas) Também é muito fácil estragar tudo.
Ao invés disso eu utilizaria URIBuilder
ou Spring's org.springframework.web.util.UriUtils.encodeQuery
ou Commons Apache HttpClient
.
A razão sendo que você tem que escapar do nome dos parâmetros da consulta (ie BalusC's answer q
) de forma diferente do valor do parâmetro.
A única desvantagem do acima (que eu descobri dolorosamente) é que URL's não são um verdadeiro subconjunto de URI's.
Código da amostra:
import org.apache.http.client.utils.URIBuilder;
URIBuilder ub = new URIBuilder("http://example.com/query");
ub.addParameter("q", "random word £500 bank \$");
String url = ub.toString();
// Result: http://example.com/query?q=random+word+%C2%A3500+bank+%24
Desde I'estou apenas a ligar a outras respostas, marquei isto como um wiki comunitário. Sinta-se à vontade para editar.