web-dev-qa-db-fra.com

Java Encodage URL: URLEncoder vs. URI

En regardant la page Web d'encodage d'URL des écoles W , il est indiqué que @ doit être codé comme %40, et que space doit être codé comme %20.

J'ai essayé à la fois URLEncoder et URI, mais ni l'un ni l'autre ne fait correctement ce qui précède:

import Java.net.URI;
import Java.net.URLEncoder;

public class Test {
    public static void main(String[] args) throws Exception {

        // Prints me%40home.com (CORRECT)
        System.out.println(URLEncoder.encode("[email protected]", "UTF-8"));

        // Prints Email+Address (WRONG: Should be Email%20Address)
        System.out.println(URLEncoder.encode("Email Address", "UTF-8"));

        // http://www.home.com/test?Email%[email protected]
        // (WRONG: it has not encoded the @ in the email address)
        URI uri = new URI("http", "www.home.com", "/test", "Email [email protected]", null);
        System.out.println(uri.toString());
    }
}

Pour une raison quelconque, URLEncoder fait correctement l'adresse e-mail mais pas les espaces, et URI fait les espaces monnaie mais pas les adresses e-mail.

Comment dois-je encoder ces 2 paramètres pour être cohérent avec ce que w3schools dit est correct (ou w3schools est-il faux?)

19
John Farrelly

Bien que je pense que la réponse de @fge est la bonne, car j'utilisais un service Web tiers qui s'appuyait sur l'encodage décrit dans l'article W3Schools, j'ai suivi la réponse de Java équivalent à l'encodeURIComponent de JavaScript qui produit une sortie identique ?

public static String encodeURIComponent(String s) {
    String result;

    try {
        result = URLEncoder.encode(s, "UTF-8")
                .replaceAll("\\+", "%20")
                .replaceAll("\\%21", "!")
                .replaceAll("\\%27", "'")
                .replaceAll("\\%28", "(")
                .replaceAll("\\%29", ")")
                .replaceAll("\\%7E", "~");
    } catch (UnsupportedEncodingException e) {
        result = s;
    }

    return result;
}
35
John Farrelly

La syntaxe URI est définie par RFC 3986 (le contenu autorisé pour une chaîne de requête est défini dans la section 3.4). URI de Java est conforme à cette RFC, avec quelques mises en garde mentionnées dans son Javadoc .

Vous remarquerez que la règle de grammaire pchar est définie par:

pchar = unreserved/pct-encoded/sub-delims/":"/"@"

Ce qui signifie un @ est légal dans une chaîne de requête.

Faire confiance à l'URI. Il va faire le truc correct, "légal".

Enfin, si vous regardez le Javadoc de URLEncoder , vous voyez qu'il indique:

Cette classe contient des méthodes statiques pour convertir une chaîne au format MIME application/x-www-form-urlencoded.

Ce qui est pas la même chose qu'une chaîne de requête telle que définie par la spécification URI.

15
fge