Codificação de URL Java de parâmetros de string de consulta

Digamos que eu tenha um URL

http://example.com/query?q= 

e eu tenho uma consulta inserida pelo usuário, como:

palavra aleatória £ 500 banco $

Quero que o resultado seja um URL corretamente codificado:

 http://example.com/query?q=random%20word%20%A3500%20bank%20%24 

Qual é a melhor maneira de conseguir isso? Eu tentei URLEncoder e criar objects URI / URL, mas nenhum deles saiu muito bem.

URLEncoder deve ser o caminho a percorrer. Você só precisa se lembrar de codificar apenas o nome e / ou o valor do parâmetro da string de consulta individual, não o URL inteiro, com certeza não o caractere separador de parâmetro da string de consulta nem o caractere separador de valor de nome do parâmetro = .

 String q = "random word £500 bank $"; String url = "http://example.com/query?q=" + URLEncoder.encode(q, "UTF-8"); 

Observe que os espaços nos parâmetros de consulta são representados por + , não %20 , o que é legitimamente válido. O %20 é geralmente usado para representar espaços no próprio URI (a parte antes do caractere separador de string de consulta URI ? ), Não na sequência de consulta (a parte após ? ).

Observe também que existem dois methods encode() . Um sem argumento de charset e outro com. Aquele sem argumento de charset está obsoleto. Nunca use e sempre especifique o argumento charset. O javadoc até mesmo recomenda explicitamente usar a codificação UTF-8, conforme exigido pelo RFC3986 e pelo W3C .

Todos os outros caracteres não são seguros e são primeiro convertidos em um ou mais bytes usando algum esquema de codificação. Então cada byte é representado pela string de 3 caracteres “% xy”, onde xy é a representação hexadecimal de dois dígitos do byte. O esquema de codificação recomendado para usar é o UTF-8 . No entanto, por motivos de compatibilidade, se uma codificação não for especificada, a codificação padrão da plataforma será usada.

Veja também:

  • O que todo desenvolvedor da Web deve saber sobre codificação de URL

Eu não usaria o URLEncoder . Além de ser incorretamente nomeado ( URLEncoder não tem nada a ver com URLs), ineficiente (ele usa um StringBuffer vez de Builder e faz um par de outras coisas que são lentas) Também é muito fácil estragar tudo.

Em vez disso, eu usaria o URIBuilder ou o Spring Apache HttpClient . A razão é que você tem que escaping do nome dos parâmetros de consulta (ou seja, a resposta do BalusC q ) de forma diferente do valor do parâmetro.

A única desvantagem para o acima (que eu descobri dolorosamente) é que as URLs não são um subconjunto verdadeiro de URI .

Código de 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 

Como estou ligando para outras respostas, marquei isso como um wiki da comunidade. Sinta-se à vontade para editar.

Você precisa primeiro criar um URI como:

  String urlStr = "http://www.example.com/CEREC® Materials & Accessories/IPS Empress® CAD.pdf" URL url= new URL(urlStr); URI uri = new URI(url.getProtocol(), url.getUserInfo(), url.getHost(), url.getPort(), url.getPath(), url.getQuery(), url.getRef()); 

Então converta esse Uri para string ASCII:

  urlStr=uri.toASCIIString(); 

Agora sua string url é completamente codificada primeiro nós fizemos uma codificação url simples e depois a convertemos em ASCII String para garantir que nenhum caractere fora do US-ASCII permaneça na string. Isto é exatamente como os navegadores fazem.

A Guava 15 agora adicionou um conjunto de simples exploradores de URL .

A biblioteca de componentes HTTP do Apache fornece uma opção interessante para construir e codificar parâmetros de consulta –

Com o uso do HttpComponents 4.x – URLEncodedUtils

Para uso do HttpClient 3.x – EncodingUtil

Aqui está um método que você pode usar em seu código para converter uma string de url e um mapa de parâmetros em uma string de URL codificada válida contendo os parâmetros de consulta.

 String addQueryStringToUrlString(String url, final Map parameters) throws UnsupportedEncodingException { if (parameters == null) { return url; } for (Map.Entry parameter : parameters.entrySet()) { final String encodedKey = URLEncoder.encode(parameter.getKey().toString(), "UTF-8"); final String encodedValue = URLEncoder.encode(parameter.getValue().toString(), "UTF-8"); if (!url.contains("?")) { url += "?" + encodedKey + "=" + encodedValue; } else { url += "&" + encodedKey + "=" + encodedValue; } } return url; } 

Eu usaria este código:

 Uri myUI = Uri.parse ("http://example.com/query").buildUpon().appendQueryParameter("q","random word A3500 bank 24").build(); 

1. Divida a URL em partes estruturais. Use java.net.URL para isso.

2. Codifique cada parte estrutural corretamente!

3. Use IDN.toASCII(putDomainNameHere) para Punycode para codificar o nome do host!

4. Use java.net.URI.toASCIIString() para codificar por cento, unicode codificado em NFC – (melhor seria NFKC!). Para mais informações, consulte: Como codificar adequadamente este URL

 URL url= new URL("http://example.com/query?q=random word £500 bank $"); URI uri = new URI(url.getProtocol(), url.getUserInfo(), IDN.toASCII(url.getHost()), url.getPort(), url.getPath(), url.getQuery(), url.getRef()); String correctEncodedURL=uri.toASCIIString(); System.out.println(correctEncodedURL); 

Impressões

 http://example.com/query?q=random%20word%20%C2%A3500%20bank%20$ 
  1. Use este: URLEncoder.encode (consulta, StandardCharsets.UTF_8.displayName ()); ou isto: URLEncoder.encode (consulta, “UTF-8”);
  2. Você pode usar o seguinte código.

     String encodedUrl1 = UriUtils.encodeQuery(query, "UTF-8");//not change String encodedUrl2 = URLEncoder.encode(query, "UTF-8");//changed String encodedUrl3 = URLEncoder.encode(query, StandardCharsets.UTF_8.displayName());//changed System.out.println("url1 " + encodedUrl1 + "\n" + "url2=" + encodedUrl2 + "\n" + "url3=" + encodedUrl3);