Digamos que eu tenho um URL
http://example.com/query?q=
e eu tenho uma consulta inserida pelo usuário, como:
palavra aleatória £ 500 bank $
Quero que o resultado seja um URL codificado corretamente:
http://example.com/query?q=random%20word%20%A3500%20bank%20%24
Qual é a melhor maneira de conseguir isso? Eu tentei URLEncoder
criar objetos URI / URL, mas nenhum deles saiu bem.
Respostas:
URLEncoder
é o caminho a percorrer. Você só precisa codificar apenas o nome e / ou o valor do parâmetro da sequência de consulta individual, e não o URL inteiro, com certeza não o caractere separador do parâmetro da sequência de consultas&
nem o caractere separador nome-valor do parâmetro=
.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 é para ser usado para representar espaços em si mesmo (a parte antes do caractere separador seqüência URI-consulta URI?
), e não na string de consulta (a parte depois?
).Observe também que existem três
encode()
métodos. Um semCharset
como segundo argumento e outro comString
como segundo argumento que lança uma exceção verificada. O semCharset
argumento está obsoleto. Nunca use e sempre especifique oCharset
argumento. O javadoc ainda recomenda explicitamente o uso da codificação UTF-8, conforme exigido pelo RFC3986 e W3C .Veja também:
fonte
URLEncoder
é para parâmetros de consulta codificados em URL, conformeapplication/x-www-form-urlencoded
regras. Os parâmetros do caminho não se enquadram nessa categoria. Você precisa de um codificador URI.Eu não usaria
URLEncoder
. Além de ter um nome incorreto (URLEncoder
não tem nada a ver com URLs), é ineficiente (usa um emStringBuffer
vez do Builder e faz algumas outras coisas que são lentas) Também é muito fácil estragar tudo.Em vez disso eu usaria
URIBuilder
ou Primavera doorg.springframework.web.util.UriUtils.encodeQuery
ou Commons ApacheHttpClient
. A razão é que você precisa escapar do nome dos parâmetros da consulta (ou seja, a resposta do BalusCq
) de maneira diferente do valor do parâmetro.A única desvantagem do que foi mencionado acima (que eu descobri dolorosamente) é que os URLs não são um verdadeiro subconjunto dos URIs .
Código de amostra:
Como estou apenas ligando para outras respostas, marquei isso como um wiki da comunidade. Sinta-se livre para editar.
fonte
URLEncoder
é como o javadoc diz que pretende codificar os parâmetros da string de consulta conformeapplication/x-www-form-urlencoded
descrito na especificação HTML: w3.org/TR/html4/interact/… . Alguns usuários realmente o confundem / abusam por codificar URIs inteiros, como aparentemente o atendedor atual.Você precisa primeiro criar um URI como:
Em seguida, converta esse Uri em string ASCII:
Agora, sua string de URL é completamente codificada. Primeiro fizemos uma codificação de URL simples e depois a convertemos em ASCII String para garantir que nenhum caractere fora do US-ASCII permaneça na string. É exatamente assim que os navegadores fazem.
fonte
URL.toURI()
não.+
substituição de espaços, mas aceitou o% 20, portanto esta solução funcionou melhor que o BalusC, obrigado!O Guava 15 agora adicionou um conjunto de escapers simples de URL .
fonte
URLEncoder
.URLEncoder
não acontece.A biblioteca Apache Http Components fornece uma opção interessante para criar e codificar parâmetros de consulta -
Com o uso do HttpComponents 4.x - URLEncodedUtils
Para uso do HttpClient 3.x - EncodingUtil
fonte
Aqui está um método que você pode usar no seu código para converter uma string de URL e um mapa de parâmetros em uma string de URL codificada válida que contenha os parâmetros de consulta.
fonte
Impressões
O que esta acontecendo aqui?
1. Divida o URL em partes estruturais. Usar
java.net.URL
para isso.2) Codifique cada parte estrutural corretamente!
3. Use
IDN.toASCII(putDomainNameHere)
para Punycode codificar o nome do host!4. Use
java.net.URI.toASCIIString()
para codificação percentual, unicode codificado por NFC - (melhor seria NFKC!). Para mais informações, consulte: Como codificar corretamente este URLEm alguns casos, é aconselhável verificar se o URL já está codificado . Substitua também os espaços codificados '+' pelos espaços codificados '% 20'.
Aqui estão alguns exemplos que também funcionarão corretamente
A solução passa em torno de 100 dos casos de teste fornecidos pelos testes da Web Plattform .
fonte
No android, eu usaria este código:
Onde
Uri
está umandroid.net.Uri
fonte
No meu caso, eu só precisava passar o URL inteiro e codificar apenas o valor de cada parâmetro. Não encontrei um código comum para fazer isso (!!), então criei este pequeno método para fazer o trabalho:
Ele usa org.apache.commons.lang3.StringUtils
fonte
Você pode usar o código a seguir.
fonte
=
e&
, o que não está correto.