Java URL encodage des paramètres de chaîne de requête

Dire que j'ai une URL

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

et j'ai une requête entrée par l'utilisateur tel que:

mot aléatoire £500 banque $

je veux que le résultat soit une URL correctement encodée:

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

Quelle est la meilleure façon d'y parvenir? J'ai essayé URLEncoder et de créer des objets URI/URL mais aucun d'eux ne sort tout à fait bien.

574
demandé sur Abdull 2012-05-28 18:10:45

9 réponses

URLEncoder ça devrait être la solution. Vous devez seulement garder à l'esprit de coder seulement le nom et/ou la valeur du paramètre de chaîne de requête individuel, pas L'URL entière, pour sûr pas le caractère de séparateur de paramètre de chaîne de requête & ni le caractère de séparateur de nom-valeur de paramètre = .

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

notez que les espaces dans les paramètres de requête sont représentés par + , et non %20 , qui est légitimement valable. Le %20 doit généralement être utilisé pour représenter des espaces dans URI lui-même (la partie avant le caractère de séparateur de chaîne de requête ? ), pas dans la chaîne de requête (la partie après ? ).

il y a aussi deux méthodes encode() . Une sans argument de charset et une autre avec. Celui sans argument charset est déprécié. Ne l'utilisez jamais et spécifiez toujours l'argument charset. Le javadoc recommande même explicitement D'utiliser L'encodage UTF-8, comme prescrit par RFC3986 et W3C .

tous les autres caractères sont dangereux et sont d'abord convertis en un ou plusieurs octets à l'aide d'un schéma d'encodage. Ensuite chaque octet est représenté par la chaîne de 3 caractères "%xy", où xy est la représentation hexadécimale à deux chiffres du octet. l'encodage recommandé schéma à utiliser est UTF-8 . Cependant, pour des raisons de compatibilité, si l'encodage n'est pas spécifié, alors l'encodage par défaut de la plate-forme est utilisée.

voir aussi:

959
répondu BalusC 2016-01-14 07:59:00

Je n'utiliserais pas URLEncoder . En plus d'être mal nommé ( URLEncoder n'a rien à voir avec les URLs), inefficace (il utilise un StringBuffer au lieu de Builder et fait un couple d'autres choses qui sont lents) sa façon aussi trop facile de le faire foirer.

à la place, j'utiliserais URIBuilder ou "Spring's org.springframework.web.util.UriUtils.encodeQuery ou" Commons Apache HttpClient . La raison étant que vous devez échapper aux paramètres de requête nom (réponse de BalusC q ) différent de la valeur du paramètre.

le seul inconvénient de ce qui précède (que j'ai trouvé douloureusement) est que les URL ne sont pas un vrai sous-ensemble de D'URI .

code échantillon:

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

comme je ne fais que lier à d'autres réponses, j'ai noté ceci comme un wiki communautaire. N'hésitez pas à modifier.

140
répondu Adam Gent 2017-07-17 11:39:34

vous devez d'abord créer un URI comme:

    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());

convertissez alors cet Uri en chaîne ASCII:

    urlStr=uri.toASCIIString();

maintenant votre chaîne d'url est entièrement encodée d'abord nous avons fait l'encodage d'url simple et ensuite nous l'avons converti en chaîne ASCII pour s'assurer qu'aucun caractère en dehors de nous-ASCII ne reste dans la chaîne. C'est exactement ce que font les navigateurs.

86
répondu M Abdul Sami 2014-09-09 00:52:06

Guava 15 a maintenant ajouté un ensemble d'échappements d'URL .

29
répondu Emmanuel Touzery 2017-06-15 20:34:41

Apache bibliothèque de composants Http fournit une option soignée pour la construction et l'encodage des paramètres de requête -

With Httpcomposants 4.x utilisation - URLEncodedUtils

Pour HttpClient 3.x utilisation - EncodingUtil

6
répondu Sashi 2016-07-06 20:49:47

Voici une méthode que vous pouvez utiliser dans votre code pour convertir une chaîne d'url et une carte de paramètres en une chaîne d'url encodée valide contenant les paramètres de la requête.

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
répondu Pellet 2016-11-02 00:34:30

1. divise L'URL en parties structurelles. Utilisez java.net.URL pour cela.

2. encodez chaque pièce de structure correctement!

3. utiliser IDN.toASCII(putDomainNameHere) à Punycode encoder le nom d'hôte!

4. Utiliser java.net.URI.toASCIIString() % -encoder, NFC codé en unicode (mieux serait NFKC!). Pour plus d'info voir: comment coder correctement cette 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);

Imprime

http://example.com/query?q=random%20word%20%C2%A3500%20bank%20$
1
répondu jschnasse 2018-04-12 15:06:28

sous android j'utiliserais ce code:

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

Uri est un android.net.Uri

1
répondu Sharjeel Lasharie 2018-09-21 20:29:54
  1. utilisez cette URLEncoder.encoder (query, StandardCharsets.UTF_8.displayName()); ou Ceci: URLEncoder.encoder (query, "UTF-8");
  2. vous pouvez utiliser le code suivant.

    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
répondu Xuelian Han 2017-02-21 07:59:58