Codificando parameters de Consulta de URL em Java

Como um codificar parâmetros de consulta para ir em uma URL em Java? Eu sei, isso parece uma pergunta óbvia e já feita.

Existem duas sutilezas das quais não tenho certeza:

  1. Os espaços devem ser codificados no URL como “+” ou “% 20”? No Google Chrome, se eu digitar “http://google.com/foo=?bar me”, o Chrome será alterado para% 20
  2. É necessário / correto codificar dois pontos “:” como% 3B? O Chrome não

Notas:

  • java.net.URLEncoder.encode parece não funcionar, parece ser para dados de codificação para ser formulário enviado. Por exemplo, ele codifica o espaço como + vez de %20 e codifica o cólon, o que não é necessário.
  • java.net.URI não codifica parâmetros de consulta

java.net.URLEncoder.encode(String s, String encoding) pode ajudar também. Ele segue o formulário HTML que codifica application/x-www-form-urlencoded .

 URLEncoder.encode(query, "UTF-8"); 

Por outro lado, a codificação percentual (também conhecida como codificação de URL ) codifica o espaço com %20 . Colon é um caractere reservado, então : continuará a ser um cólon, após a codificação.

EDIT: URIUtil não está mais disponível em versões mais recentes, melhor resposta na URL de codificação Java ou pelo Sr. Sindi neste encadeamento.


URIUtil do Apache httpclient é realmente útil, embora existam algumas alternativas

 URIUtil.encodeQuery(url); 

Por exemplo, ele codifica o espaço como “+” em vez de “% 20”

Ambos são perfeitamente válidos no contexto certo . Embora, se você realmente preferisse, poderia emitir uma substituição de string.

Infelizmente, URLEncoder.encode () não produz uma codificação percentual válida (conforme especificado em http://tools.ietf.org/html/rfc3986#section-2.1 ).

URLEncoder.encode () codifica tudo muito bem, exceto que o espaço é codificado para “+”. Todos os codificadores Java URI que eu encontrei apenas expõem methods públicos para codificar a consulta, fragment, partes do caminho etc. – mas não expõem a codificação “bruta”. Isso é lamentável, pois o fragment e a consulta podem codificar o espaço para +, portanto, não queremos usá-los. O caminho é codificado corretamente, mas é “normalizado” primeiro, portanto, também não podemos usá-lo para codificação “genérica”.

Melhor solução que eu poderia propor:

 return URLEncoder.encode(raw, "UTF-8").replaceAll("\\+", "%20"); 

Se replaceAll() é muito lento para você, eu acho que a alternativa é rolar seu próprio codificador …

EDIT: Eu tinha este código aqui primeiro, que não codifica “?”, “&”, “=” Corretamente:

 //don't use - doesn't properly encode "?", "&", "=" new URI(null, null, null, raw, null).toString().substring(1); 

Não é necessário codificar dois pontos como% 3B na consulta, embora isso não seja ilegal.

 URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ] query = *( pchar / "/" / "?" ) pchar = unreserved / pct-encoded / sub-delims / ":" / "@" unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" pct-encoded = "%" HEXDIG HEXDIG sub-delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "=" 

Parece também que apenas os espaços codificados por percentual são válidos, pois duvido que o espaço seja um ALPHA ou um DIGIT

olhe para a especificação URI para mais detalhes.

O construtor em Java URLEncoder está fazendo o que é suposto, e você deve usá-lo.

Um “+” ou “% 20” são substitutos válidos para um caractere de espaço em um URL. Qualquer um vai funcionar.

Um “:” deve ser codificado, pois é um caractere separador. ou seja, http: // foo ou ftp: // bar . O fato de que um determinado navegador pode manipulá-lo quando não está codificado não o torna correto. Você deveria codificá-los.

Por uma questão de boa prática, certifique-se de usar o método que usa um parâmetro de codificação de caracteres. O UTF-8 é geralmente usado lá, mas você deve fornecê-lo explicitamente.

 URLEncoder.encode(yourUrl, "UTF-8");