Question Codage d'URL Java des paramètres de chaîne de requête


Dites que j'ai une URL

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

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

mot au hasard £ 500 bank $

Je veux que le résultat soit une URL correctement codée:

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

Quel est le meilleur moyen d'y parvenir? j'ai essayé URLEncoder et créer des objets URI / URL mais aucun d'eux ne sort tout à fait correct.


561
2018-05-28 14:10


origine


Réponses:


URLEncoder devrait être le chemin à parcourir. Vous avez seulement besoin de garder à l'esprit d'encoder seulement le nom et / ou la valeur du paramètre de la chaîne de requête individuelle, pas l'URL complète, à coup sûr pas le caractère de la chaîne de caractères du séparateur & ni le caractère 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 +, ne pas %20, qui est légitimement valide. le %20 est généralement utilisé pour représenter les espaces dans l'URI lui-même (la partie avant le caractère séparateur de chaîne de requête URI ?), pas dans la chaîne de requête (la partie après ?).

Notez également qu'il y a deux encode() méthodes Un sans argument charset et un autre avec. Celui sans argument charset est obsolète. Ne l'utilisez jamais et spécifiez toujours l'argument charset. le javadoc recommande même explicitement d'utiliser l'encodage UTF-8, tel que mandaté par RFC3986 et W3C.

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

Voir également:


934
2018-05-28 14:15



Je n'utiliserais pas URLEncoder. En plus d'être incorrectement nommé (URLEncoder n'a rien à voir avec les URL), inefficace (il utilise un StringBuffer au lieu de Builder et fait un couple d'autres choses qui sont lentes) C'est aussi beaucoup trop facile de le bousiller.

Au lieu de cela j'utiliserais URIBuilder ou Le printemps org.springframework.web.util.UriUtils.encodeQuery ou Commons Apache HttpClient. La raison étant que vous devez échapper le nom des paramètres de la requête (par exemple la réponse de BalusC q) différemment de la valeur du paramètre.

Le seul inconvénient de ce qui précède (que j'ai découvert douloureusement) est que Les URL ne sont pas un véritable sous-ensemble d'URI.

Exemple de code:

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 marqué cela comme un wiki communautaire. N'hésitez pas à modifier.


132
2017-09-09 00:52



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

Puis convertissez ce Uri en chaîne ASCII:

    urlStr=uri.toASCIIString();

Maintenant, votre chaîne d'URL est complètement encodée d'abord, nous avons fait un simple encodage d'URL et ensuite nous l'avons converti en chaîne ASCII pour nous assurer qu'aucun caractère en dehors de US-ASCII ne reste en chaîne. C'est exactement ce que font les navigateurs.


83
2017-12-04 13:18



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


28
2017-07-06 20:49



La bibliothèque Apache Http Components fournit une option soignée pour construire et encoder des paramètres de requête -

Avec HttpComponents 4.x utilisation -     URLEncodedUtils

Pour l'utilisation de HttpClient 3.x -     EncodingUtil


5
2017-11-01 06:47



Voici une méthode que vous pouvez utiliser dans votre code pour convertir une chaîne URL et une carte de paramètres en une chaîne URL codé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
2018-06-01 12:23



J'utiliserais ce code:

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

1
2018-04-12 12:43



1. Diviser l'URL en parties structurelles. Utilisation java.net.URL  pour ça.

2.  Encoder chaque partie structurelle correctement!

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

4. Utilisation java.net.URI.toASCIIString() pour coder en pourcentage, unicode codé NFC - (mieux serait NFKC!). Pour plus d'informations, voir: Comment encoder 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);

Impressions

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

1
2018-02-21 07:54



  1. Utilisez ceci: URLEncoder.encode (query, StandardCharsets.UTF_8.displayName ()); ou ceci: URLEncoder.encode (requête, "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