Pregunta Codificación de URL Java de parámetros de cadena de consulta


Digamos que tengo una URL

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

y tengo una consulta ingresada por el usuario como:

palabra al azar £ 500 bank $

Quiero que el resultado sea una URL codificada correctamente:

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

¿Cuál es la mejor manera de lograr esto? Lo intenté URLEncoder y crear objetos URI / URL, pero ninguno de ellos sale del todo bien.


561
2018-05-28 14:10


origen


Respuestas:


URLEncoder debería ser el camino a seguir. Solo necesitas tener en cuenta para codificar solamente el nombre y / o valor del parámetro de cadena de consulta individual, no la URL completa, con seguridad no el carácter separador de parámetro de cadena de consulta & ni el carácter separador de nombre-valor del parámetro =.

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

Tenga en cuenta que los espacios en los parámetros de consulta están representados por +no %20, que es legítimamente válido los %20 generalmente se usa para representar espacios en el URI en sí mismo (la parte antes del carácter separador de cadena de consulta de URI) ?), no en la cadena de consulta (la parte después ?)

También tenga en cuenta que hay dos encode() métodos. Uno sin argumento charset y otro con. El que no tiene argumento de conjunto de caracteres está en desuso. Nunca lo use y siempre especifique el argumento charset. los javadoc incluso explícitamente recomienda usar la codificación UTF-8, según lo ordenado por RFC3986 y W3C.

Todos los demás caracteres son inseguros y se convierten primero en uno o más bytes utilizando algún esquema de codificación. Entonces cada byte se representa con la cadena de 3 caracteres "% xy", donde xy es la representación hexadecimal de dos dígitos del byte. El esquema de codificación recomendado para usar es UTF-8. Sin embargo, por razones de compatibilidad, si no se especifica una codificación, entonces se utiliza la codificación predeterminada de la plataforma.

Ver también:


934
2018-05-28 14:15



No usaría URLEncoder. Además de ser incorrectamente nombrado (URLEncoder no tiene nada que ver con las URL), ineficiente (usa un StringBuffer en lugar de Builder y hace un par de otras cosas que son lentas) También es demasiado fácil arruinarlo.

En cambio, usaría URIBuilder o Muelles org.springframework.web.util.UriUtils.encodeQuery o Apache común HttpClient. La razón es que tienes que escapar del nombre de los parámetros de consulta (es decir, la respuesta de BalusC q) de forma diferente que el valor del parámetro.

El único inconveniente de lo anterior (que descubrí dolorosamente) es que Las URL no son un verdadero subconjunto de URI.

Código de muestra:

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 solo estoy enlazando a otras respuestas, marqué esto como una wiki comunitaria. Siéntase libre de editar.


132
2017-09-09 00:52



Primero debe crear un 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());

Luego convierte esa cadena de Uri a ASCII:

    urlStr=uri.toASCIIString();

Ahora su cadena url está completamente codificada, primero hicimos una simple codificación url y luego la convertimos en ASCII String para asegurarnos de que ningún carácter fuera de US-ASCII permanezca en la cadena. Esto es exactamente lo que hacen los navegadores.


83
2017-12-04 13:18



Guava 15 ahora ha agregado un conjunto de escapistas de URL directos.


28
2017-07-06 20:49



La biblioteca de componentes de Apache Http ofrece una opción ordenada para construir y codificar parámetros de consulta -

Con el uso de HttpComponents 4.x -     URLEncodedUtils

Para el uso de HttpClient 3.x:     EncodingUtil


5
2017-11-01 06:47



Este es un método que puede usar en su código para convertir una cadena de URL y un mapa de parámetros en una cadena de url codificada válida que contiene los parámetros de consulta.

String addQueryStringToUrlString(String url, final Map<Object, Object> parameters) throws UnsupportedEncodingException {
    if (parameters == null) {
        return url;
    }

    for (Map.Entry<Object, Object> 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;
}

5
2018-06-01 12:23



Yo usaría este código:

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

1
2018-04-12 12:43



1. Divide URL en partes estructurales. Utilizar java.net.URL  para ello.

2.  ¡Codifique cada parte estructural correctamente!

3. Utilizar IDN.toASCII(putDomainNameHere) a Punycode codificar el nombre de host!

4. Utilizar java.net.URI.toASCIIString() para codificar por ciento, codificar unicode con codificación NFC (¡mejor sería NFKC!). Para obtener más información, consulte: Cómo codificar correctamente esta 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);

Huellas dactilares

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

1
2018-02-21 07:54



  1. Use esto: URLEncoder.encode (query, StandardCharsets.UTF_8.displayName ()); o esto: URLEncoder.encode (consulta, "UTF-8");
  2. Puedes usar el siguiente 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);
    

-2