Cómo codificar URL para evitar caracteres especiales en Java? [duplicar]


Esta pregunta ya tiene una respuesta aquí:

Necesito código java para codificar URL para evitar caracteres especiales como espacios y % y & ...etc

Author: halfer, 2010-12-31

6 answers

La construcción de URL es complicada porque las diferentes partes de la URL tienen reglas diferentes para los caracteres permitidos: por ejemplo, el signo más está reservado en el componente de consulta de una URL porque representa un espacio, pero en el componente de ruta de la URL, un signo más no tiene un significado especial y los espacios están codificados como "%20".

RFC 2396 explica (en la sección 2.4.2) que una URL completa siempre está en su forma codificada: toma las cadenas para los componentes individuales (esquema, autoridad, camino, etc.), codificar cada uno de acuerdo a sus propias reglas, y luego combinarlos en la cadena URL completa. Intentar construir una cadena URL sin codificar completa y luego codificarla por separado conduce a errores sutiles, como espacios en la ruta que se cambian incorrectamente a signos más (que un servidor compatible con RFC interpretará como signos más reales, no espacios codificados).

En Java, la forma correcta de construir una URL es con el URI clase. Utilice uno de los argumentos múltiples constructores que toman los componentes URL como cadenas separadas, y escapará cada componente correctamente de acuerdo con las reglas de ese componente. El método toASCIIString() le da una cadena correctamente escapada y codificada que puede enviar a un servidor. Para decodificar una URL, construir un objeto URI utilizando el constructor de una sola cadena y luego utilizar los métodos de acceso (como getPath()) para recuperar los componentes decodificados.

¡No uses la clase URLEncoder! A pesar del nombre, esa clase en realidad lo hace Codificación de formulario HTML, no codificación de URL. Es no correcto concatenar cadenas sin codificar para hacer una URL "sin codificar" y luego pasarla a través de un URLEncoder. Hacerlo dará lugar a problemas (en particular el mencionado con respecto a los espacios y signos más en el camino).

 64
Author: Wyzard,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-12-31 17:50:13

Esto es un duplicado de la siguiente pregunta. Puede encontrar información más detallada y discusión sobre este tema en la siguiente pregunta

Codificación de direcciones URL HTTP en Java

public class URLParamEncoder {

    public static String encode(String input) {
        StringBuilder resultStr = new StringBuilder();
        for (char ch : input.toCharArray()) {
            if (isUnsafe(ch)) {
                resultStr.append('%');
                resultStr.append(toHex(ch / 16));
                resultStr.append(toHex(ch % 16));
            } else {
                resultStr.append(ch);
            }
        }
        return resultStr.toString();
    }

    private static char toHex(int ch) {
        return (char) (ch < 10 ? '0' + ch : 'A' + ch - 10);
    }

    private static boolean isUnsafe(char ch) {
        if (ch > 128 || ch < 0)
            return true;
        return " %$&+,/:;=?@<>#%".indexOf(ch) >= 0;
    }

}
 11
Author: fmucar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 10:31:30

Si no desea hacerlo manualmente, utilice Apache Commons - Codec library. La clase que estás viendo es: org.apache.commons.codec.net.URLCodec

String final url = "http://www.google.com?...."
String final urlSafe = org.apache.commons.codec.net.URLCodec.encode(url);
 5
Author: langerra.com,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-12-31 17:17:33

Me haría eco de lo que Wyzard escribió {[3] } pero añadiría que:

  • para los parámetros de consulta, la codificación HTML es a menudo exactamente lo que el servidor espera; fuera de estos, es correcto que URLEncoder no se debe usar
  • la especificación URI más reciente es RFC 3986 , por lo que debe referirse a eso como una fuente primaria

Escribí una entrada de blog hace un tiempo sobre este tema: Java: manejo seguro de caracteres y construcción de URL

 1
Author: McDowell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:10:11

También pasé bastante tiempo con este problema, así que esa es mi solución:

String urlString2Decode = "http://www.test.com/äüö/path with blanks/";
String decodedURL = URLDecoder.decode(urlString2Decode, "UTF-8");
URL url = new URL(decodedURL);
URI uri = new URI(url.getProtocol(), url.getUserInfo(), url.getHost(), url.getPort(), url.getPath(), url.getQuery(), url.getRef());
String decodedURLAsString = uri.toASCIIString();
 1
Author: TomTom,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-17 23:08:36

Aquí está mi solución que es bastante fácil:

En lugar de codificar la url en sí, codifiqué los parámetros que estaba pasando porque el parámetro era la entrada del usuario y el usuario podía ingresar cualquier cadena inesperada de caracteres especiales, por lo que esto me funcionó bien:)

String review="User input"; /*USER INPUT AS STRING THAT WILL BE PASSED AS PARAMTER TO URL*/
try {
    review = URLEncoder.encode(review,"utf-8");
    review = review.replace(" " , "+");
} catch (UnsupportedEncodingException e) {
    e.printStackTrace();
}
String URL = "www.test.com/test.php"+"?user_review="+review;
 -1
Author: Shahid Sarwar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-13 23:59:57