Meu aplicativo independente Java obtém uma URL (que aponta para um arquivo) do usuário e preciso acessá-lo e fazer o download. O problema que estou enfrentando é que não consigo codificar o endereço de URL HTTP corretamente ...
Exemplo:
URL: http://search.barnesandnoble.com/booksearch/first book.pdf
java.net.URLEncoder.encode(url.toString(), "ISO-8859-1");
retorna-me:
http%3A%2F%2Fsearch.barnesandnoble.com%2Fbooksearch%2Ffirst+book.pdf
Mas o que eu quero é
http://search.barnesandnoble.com/booksearch/first%20book.pdf
(espaço substituído por% 20)
Eu acho que URLEncoder
não foi projetado para codificar URLs HTTP ... O JavaDoc diz "Classe de utilitário para codificação de formulário HTML" ... Existe alguma outra maneira de fazer isso?
Respostas:
A classe java.net.URI pode ajudar; na documentação da URL que você encontra
Use um dos construtores com mais de um argumento, como:
(o construtor de argumento único do URI NÃO escapa caracteres ilegais)
Somente caracteres ilegais são escapados pelo código acima - NÃO escapa caracteres não-ASCII (veja o comentário de fatih).
O
toASCIIString
método pode ser usado para obter uma String apenas com caracteres US-ASCII:Para um URL com uma consulta como
http://www.google.com/ig/api?weather=São Paulo
, use a versão de 5 parâmetros do construtor:fonte
java.net.URI
: funcionou perfeitamente (Java 1.6). Eu mencionaria o nome completo da classe se não fosse o Java padrão e o link apontasse para a documentação dejava.net.URI
. E, pelo comentário de Sudhakar, ele resolveu o problema sem incluir nenhuma "biblioteca comum"!Esteja avisado de que a maioria das respostas acima é INCORRETA.
A
URLEncoder
classe, apesar do nome, NÃO é o que precisa estar aqui. É lamentável que a Sun tenha chamado essa classe tão irritantemente.URLEncoder
destina-se a transmitir dados como parâmetros, não a codificar o próprio URL.Em outras palavras,
"http://search.barnesandnoble.com/booksearch/first book.pdf"
é o URL. Os parâmetros seriam, por exemplo"http://search.barnesandnoble.com/booksearch/first book.pdf?parameter1=this¶m2=that"
,. Os parâmetros são para o que você usariaURLEncoder
.Os dois exemplos a seguir destacam as diferenças entre os dois.
O seguinte produz os parâmetros incorretos, de acordo com o padrão HTTP. Observe que oe comercial (&) e mais (+) estão codificados incorretamente.
O seguinte produzirá os parâmetros corretos, com a consulta codificada corretamente. Observe os espaços, e comercial e marcas de mais.
fonte
query = URLEncoder.encode(key) + "=" + URLEncoder.encode(value)
. Os documentos dizem apenas que "qualquer caractere que não seja um URI legal é citado".Vou adicionar uma sugestão aqui destinada aos usuários do Android. Você pode fazer isso, evitando a necessidade de obter bibliotecas externas. Além disso, todas as soluções de busca / substituição de caracteres sugeridas em algumas das respostas acima são perigosas e devem ser evitadas.
Faça uma tentativa:
Você pode ver que, neste URL específico, preciso ter esses espaços codificados para que eu possa usá-lo para uma solicitação.
Isso tira proveito de alguns recursos disponíveis nas classes do Android. Primeiro, a classe de URL pode quebrar um URL em seus componentes adequados, para que você não precise executar nenhum trabalho de pesquisa / substituição de string. Em segundo lugar, essa abordagem aproveita o recurso da classe URI de componentes que escapam adequadamente quando você constrói um URI por meio de componentes, e não a partir de uma única sequência.
A vantagem dessa abordagem é que você pode pegar qualquer string de URL válida e fazê-la funcionar sem precisar de nenhum conhecimento especial dela.
fonte
#
.uma solução que desenvolvi e muito mais estável do que qualquer outra:
fonte
String utf8Input = new String(Charset.forName("UTF-8").encode(input).array());
(tomadas a partir daqui )Se você tiver um URL, poderá passar url.toString () para esse método. Primeira decodificação, para evitar a codificação dupla (por exemplo, a codificação de um espaço resulta em% 20 e a codificação de um sinal de porcentagem em% 25, portanto, a codificação dupla transformará um espaço em% 2520). Em seguida, use o URI conforme explicado acima, adicionando todas as partes da URL (para não descartar os parâmetros de consulta).
fonte
Sim, a codificação de URL codifica essa sequência para que ela seja passada corretamente em um URL para um destino final. Por exemplo, você não pode ter http://stackoverflow.com?url=http://yyy.com . UrlEncoding o parâmetro fixaria o valor desse parâmetro.
Então, eu tenho duas opções para você:
Você tem acesso ao caminho separado do domínio? Nesse caso, você poderá simplesmente UrlEncode o caminho. No entanto, se esse não for o caso, a opção 2 pode ser para você.
Obtenha o commons-httpclient-3.1. Isso tem uma classe URIUtil:
System.out.println (URIUtil.encodePath (" http://example.com/x y", "ISO-8859-1"));
Isso produzirá exatamente o que você está procurando, pois codificará apenas a parte do caminho do URI.
Para sua informação, você precisará do codec comum e do log comum para esse método funcionar em tempo de execução.
fonte
URIUtil
soluçãoNitpicking: uma string que contém um caractere de espaço em branco por definição não é um URI. Então, o que você está procurando é um código que implemente o escape de URI definido na Seção 2.1 da RFC 3986 .
fonte
Infelizmente, ele
org.apache.commons.httpclient.util.URIUtil
está obsoleto e areplacement org.apache.commons.codec.net.URLCodec
codificação é adequada para postagens de formulários, não em URLs reais. Então eu tive que escrever minha própria função, que faz um único componente (não é adequado para cadeias de consulta inteiras que possuem? 'E' s)fonte
URLEncoding pode codificar URLs HTTP muito bem, como você infelizmente descobriu. A string que você inseriu, " http://search.barnesandnoble.com/booksearch/first book.pdf", foi correta e completamente codificada em um formulário codificado em URL. Você poderia transmitir toda a longa cadeia de devoradores que retornou como parâmetro em um URL, e poderia ser decodificado de volta para exatamente a cadeia pela qual você passou.
Parece que você deseja fazer algo um pouco diferente de passar todo o URL como parâmetro. Pelo que entendi, você está tentando criar um URL de pesquisa parecido com " http://search.barnesandnoble.com/booksearch/whateverTheUserPassesIn ". A única coisa que você precisa codificar é o bit "WhateverTheUserPassesIn", então talvez tudo o que você precise fazer seja algo assim:
Isso deve produzir algo bastante mais válido para você.
fonte
Se alguém não quiser adicionar uma dependência ao seu projeto, essas funções podem ser úteis.
Passamos a parte 'path' da nossa URL para aqui. Você provavelmente não deseja passar o URL completo como parâmetro (as cadeias de consulta precisam de escapes diferentes, etc.).
E testes:
fonte
Ainda existe um problema se você tiver um "/" (% 2F) codificado no seu URL.
A RFC 3986 - Seção 2.2 diz: "Se os dados para um componente de URI entrarem em conflito com a finalidade de um caractere reservado como delimitador, os dados conflitantes deverão ser codificados em porcentagem antes que o URI seja formado". (RFC 3986 - Seção 2.2)
Mas há um problema com o Tomcat:
Portanto, se você tiver um URL com o caractere% 2F, o Tomcat retornará: "400 URI inválido: noSlash"
Você pode alternar a correção de bug no script de inicialização do Tomcat:
fonte
Li as respostas anteriores para escrever meu próprio método, porque não consegui que algo funcionasse corretamente usando a solução das respostas anteriores. Parece bom para mim, mas se você encontrar um URL que não funcione com isso, informe-me.
fonte
Eu concordo com Matt. Na verdade, nunca o vi bem explicado nos tutoriais, mas uma questão é como codificar o caminho da URL, e uma questão muito diferente é como codificar os parâmetros anexados à URL (a parte da consulta, atrás do "? "símbolo). Eles usam codificação semelhante, mas não é a mesma.
Especialmente para a codificação do caractere de espaço em branco. O caminho da URL precisa ser codificado como% 20, enquanto a parte da consulta permite% 20 e também o sinal "+". A melhor idéia é testá-lo por nós mesmos em nosso servidor da Web, usando um navegador da Web.
Nos dois casos, eu sempre codificaria COMPONENT BY COMPONENT , nunca a string inteira. Na verdade, o URLEncoder permite isso para a parte da consulta. Para a parte do caminho, você pode usar o URI da classe, embora neste caso solicite a cadeia inteira, não um único componente.
Enfim, acredito que a melhor maneira de evitar esses problemas é usar um design pessoal não conflituoso. Quão? Por exemplo, eu nunca nomearia diretórios ou parâmetros usando outros caracteres além de aZ, AZ, 0-9 e _. Dessa forma, a única necessidade é codificar o valor de cada parâmetro, pois ele pode vir de uma entrada do usuário e os caracteres usados são desconhecidos.
fonte
Talvez possa experimentar o UriUtils em org.springframework.web.util
fonte
Você também pode usar
GUAVA
e localizar o caminho:UrlEscapers.urlFragmentEscaper().escape(relativePath)
fonte
Além da resposta de Carlos Heuberger: se for necessário um valor diferente do padrão (80), o construtor 7 param deve ser usado:
fonte
Peguei o conteúdo acima e mudei um pouco. Gosto primeiro da lógica positiva e achei que um HashSet poderia oferecer um desempenho melhor do que algumas outras opções, como pesquisar por uma String. Embora eu não tenha certeza se a penalidade de autoboxing vale a pena, mas se o compilador otimizar para caracteres ASCII, o custo do boxe será baixo.
fonte
Use a seguinte solução Java padrão (passa em torno de 100 dos casos de teste fornecidos pelos testes do Web Plattform ):
0. Teste se o URL já está codificado .
1. Divida o URL em partes estruturais. Use
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!).Encontre mais aqui: https://stackoverflow.com/a/49796882/1485527
fonte
Eu criei um novo projeto para ajudar a construir URLs HTTP. A biblioteca codificará automaticamente os segmentos de caminho e os parâmetros de consulta.
Você pode visualizar a fonte e baixar um binário em https://github.com/Widen/urlbuilder
O URL de exemplo nesta pergunta:
produz
http://search.barnesandnoble.com/booksearch/first%20book.pdf
fonte
Eu tive o mesmo problema. Resolvido isso cancelando:
Ele codifica a string, mas ignora ":" e "/".
fonte
Eu uso isso
adicione essa dependência
fonte
Eu desenvolvo uma biblioteca que serve a esse propósito: galimatias . Ele analisa o URL da mesma maneira que os navegadores da web. Ou seja, se um URL funcionar em um navegador, ele será analisado corretamente por galimatias .
Nesse caso:
Vamos dar-lhe:
http://search.barnesandnoble.com/booksearch/first%20book.pdf
. Claro que esse é o caso mais simples, mas funcionará com qualquer coisa, muito alémjava.net.URI
.Você pode conferir em: https://github.com/smola/galimatias
fonte
Você pode usar uma função como esta. Conclua e modifique-o conforme sua necessidade:
Exemplo de uso:
O resultado é: http://www.growup.com/folder/int%C3%A9rieur-%C3%A0_vendre?o=4
fonte
String url = "" http://search.barnesandnoble.com/booksearch/ ;
Acho que isso será constante e apenas o nome do arquivo será alterado dinamicamente, portanto, obtenha o nome do arquivo
Nome do arquivo da string; // obtém o nome do arquivo
String urlEnc = url + fileName.replace ("", "% 20");
fonte
E se:
public String UrlEncode (String in_) {
}
fonte