2011-03-16 21 views
75

¿Cómo se codifican los parámetros de consulta para ir en una url en Java? Lo sé, esto parece una pregunta obvia y ya hecha.Codificación de parámetros de consulta de URL en Java

Hay dos sutilezas que no estoy seguro de:

  1. En caso de espacios se van a codificar en la URL como "+" o como "% 20"? En Chrome, si escribo "http://google.com/foo=?bar me", Chrome lo cambia para que se codifique con% 20
  2. ¿Es necesario/correcto codificar dos puntos ":" como% 3B? Chrome no.

Notas:

  • java.net.URLEncoder.encode no parece funcionar, parece ser para codificar datos para ser formulario enviado. Por ejemplo, codifica espacio como + en lugar de %20, y codifica dos puntos, que no es necesario.
  • java.net.URI no codifica parámetros de consulta
+0

Esta pregunta parece útil: http://stackoverflow.com/questions/444112/how-do-i- encode-uri-p arameter-values ​​ –

+2

la estructura de la parte de consulta depende del servidor, aunque la mayoría espera pares de clave/valor 'application/x-www-form-urlencoded'. Consulte aquí para obtener más información: http://illegalargumentexception.blogspot.com/2009/12/java-safe-character-handling-and-url.html – McDowell

Respuesta

88

java.net.URLEncoder.encode(String s, String encoding) pueden ayudar también. Sigue la codificación de formulario HTML application/x-www-form-urlencoded.

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

Por otro lado, Percent-encoding (también conocido como URL encoding) codifica espacio con %20. Colón es un carácter reservado, por lo que : seguirá siendo un punto, después de la codificación.

+2

Mencioné que no creía que la codificación de URL, en cambio, codifica los datos que se enviarán a través de un formulario. comentarios? –

+0

Eso es porque 'URLEncoder' se conforma al formato MIME' application/x-www-form-urlencoded' (que es una codificación de formulario HTML válida). Supongo que eso no es lo que estás buscando. –

+0

Correcto, ¿entonces eso no descalifica su respuesta? O bien, ¿está diciendo que su resultado sigue siendo válido, simplemente más estricto de lo necesario? –

14

EDIT: URIUtil ya no está disponible en las versiones más recientes, mejor respuesta al Java - encode URL o por el Sr. Sindi en este hilo.


URIUtil de httpclient Apache es realmente útil, aunque hay algunos alternatives

URIUtil.encodeQuery(url); 

Por ejemplo, se codifica espacio como "+" en lugar de "% 20"

Ambos son perfectly valid in the right context. Aunque si realmente lo prefiere, podría emitir un reemplazo de cadena.

+0

Tendría que estar de acuerdo. Usa HttpClient, serás mucho más feliz. – DaShaun

+0

Eso parece prometedor, ¿conseguiste un enlace por casualidad? Busco en Google pero encuentro muchos. –

+0

Este método no parece estar presente en HttpClient 4.1? http://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache/http/client/utils/URIUtils.html –

7

No es necesario codificar dos puntos como% 3B en la consulta, aunque hacerlo no es ilegal.

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

También parece que sólo espacios codificada por ciento-son válidos, ya que dudo que el espacio es un alfa o con un dígito

vistazo a the URI specification para más detalles.

+0

Pero hacerlo puede cambiar el significado del URI, ya que la interpretación de la cadena de consulta depende del servidor. Si está produciendo una cadena de consulta 'application/x-www-form-urlencoded', cualquiera está bien. Si está arreglando una URL que el usuario tipeó/pegó, ':' se debe dejar en paz. –

+0

@tc. Tiene razón, si el colon se usa como un delimitador general (página 12 del RFC); sin embargo, si no se usa como un delimitador general, ambas codificaciones deberían resolverse de manera idéntica. –

+0

También debe tener cuidado ya que las URL no son realmente un subconjunto de URI: http://adamgent.com/post/25161273526/urls-are-not-a-subset-of-uris –

3

El built in Java URLEncoder está haciendo lo que se supone que debe hacer, y debe usarlo.

A "+" o "% 20" son ambos reemplazos válidos para un carácter de espacio en una URL. Cualquiera de los dos funcionará.

A ":" debe codificarse, ya que es un carácter separador. es decir, http://foo o ftp://bar. El hecho de que un navegador en particular pueda manejarlo cuando no está codificado no lo hace correcto. Deberías codificarlos.

Como una buena práctica, asegúrese de utilizar el método que toma un parámetro de codificación de caracteres. UTF-8 generalmente se usa allí, pero debe proporcionarlo explícitamente.

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

'+' es solo una representación de espacio en 'application/x-www-form-urlencoded'; no se garantiza que funcione incluso cuando esté restringido a HTTP. Del mismo modo, ':' es válido * en una cadena de consulta * y * no debe * convertirse a '% 3B'; un servidor puede elegir interpretarlos de manera diferente. –

+1

Este método también codifica barras de URL enteras y otros caracteres que forman parte, por ejemplo, 'http: //' a 'http% 3A% 2F% 2F' que no es correcto –

+0

@ToKra no se supone que codifique' http: // 'parte. El método es para parámetros de consulta y datos de formularios codificados. Sin embargo, si desea pasar la URL de otro sitio web como un parámetro de consulta, ENTONCES querrá codificarlo para evitar confundir el analizador de URL. – beldaz

7

Desafortunadamente, URLEncoder.encode() no produce válido por ciento-codificación (como se especifica en http://tools.ietf.org/html/rfc3986#section-2.1).

URLEncoder.encode() codifica todo muy bien, excepto el espacio está codificado como "+". Todos los codificadores de URI de Java que pude encontrar solo exponen los métodos públicos para codificar la consulta, el fragmento, las partes de la ruta, etc., pero no exponen la codificación "en bruto". Esto es desafortunado ya que los fragmentos y consultas tienen permitido codificar el espacio en +, por lo que no queremos usarlos. La ruta está codificada correctamente, pero está "normalizada" primero, por lo que tampoco podemos usarla para la codificación 'genérica'.

mejor solución que podría subir con:

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

Si replaceAll() es demasiado lento para usted, supongo que la alternativa es rodar su propio codificador ...

EDIT: Yo tenía este código en aquí en primer lugar que no codifica "&", "=" adecuada "?":

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

'+' es una codificación perfectamente válida de un espacio. –

+0

@LawrenceDol es cierto, pero a veces '+' puede interpretarse incorrectamente. Eche un vistazo a C# https://blogs.msdn.microsoft.com/yangxind/2006/11/08/dont-use-net-system-uri- unescapedatastring-in-url-decoding/ – Lu55

+0

Esto. Comparé varias alternativas con el resultado del método 'encodeURIComponent' de Javascript, y esta fue la única coincidencia exacta para las que probé (consultas con espacios, caracteres especiales turcos y alemanes). –

Cuestiones relacionadas