web-dev-qa-db-fra.com

Comment encoder l'URL pour éviter les caractères spéciaux en Java?

j'ai besoin de Java code pour encoder l'URL pour éviter les caractères spéciaux tels que les espaces et% et & ... etc

34
Adham

La construction de l'URL est délicate car différentes parties de l'URL ont des règles différentes pour les caractères autorisés: par exemple, le signe plus est réservé dans le composant de requête d'une URL car il représente un espace, mais dans le composant chemin de l'URL, un le signe plus n'a pas de signification particulière et les espaces sont codés comme "% 20".

RFC 2396 explique (dans la section 2.4.2) qu'une URL complète est toujours sous sa forme codée: vous prenez les chaînes pour les composants individuels (schéma, autorité, chemin, etc.), codez chacun selon à ses propres règles, puis les combiner dans la chaîne URL complète. Essayer de créer une chaîne d'URL complète non codée puis de la coder séparément entraîne des bogues subtils, comme des espaces dans le chemin d'accès qui sont incorrectement modifiés en signes plus (qu'un serveur compatible RFC interprètera comme de vrais signes plus, pas des espaces codés).

En Java, la bonne façon de construire une URL est avec la classe URI . Utilisez l'un des constructeurs multi-arguments qui prend les composants URL comme des chaînes distinctes, et il échappera correctement à chaque composant selon les règles de ce composant. La méthode toASCIIString() vous donne une chaîne correctement échappée et encodée que vous pouvez envoyer à un serveur. Pour décoder une URL, construisez un objet URI à l'aide du constructeur à chaîne unique, puis utilisez les méthodes d'accesseur (telles que la fonction getPath()) pour récupérer les composants décodés.

N'utilisez pas la classe URLEncoder! Malgré son nom, cette classe fait en fait l'encodage des formulaires HTML, pas l'encodage URL. Il est incorrect de concaténer des chaînes non codées pour créer une URL "non codée", puis de la passer par un URLEncoder. Cela entraînera des problèmes (en particulier celui mentionné ci-dessus concernant les espaces et les signes plus dans le chemin).

65
Wyzard

Ceci est un double de la question ci-dessous. Vous pouvez trouver des informations plus détaillées et une discussion sur ce problème à la question ci-dessous

Codage d'adresse 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
fmucar

Si vous ne voulez pas le faire manuellement, utilisez la bibliothèque Apache Commons - Codec. La classe que vous regardez est: 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
langerra.com

J'ai également passé un certain temps avec ce problème, c'est donc ma solution:

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
TomTom

Je voudrais faire écho à ce que Wyzard a écrit mais ajouter que:

  • pour les paramètres de requête, le codage HTML est souvent exactement ce que le serveur attend; en dehors de ceux-ci, il est correct de ne pas utiliser URLEncoder
  • la spécification d'URI la plus récente est RFC 3986 , vous devez donc vous y référer en tant que source principale

J'ai écrit un article de blog à ce sujet il y a quelque temps: Java: gestion sécurisée des caractères et création d'URL

1
McDowell