Java URL encoding de parametrii șirului de interogare

Spune că am o adresă URL

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

și am o întrebare introduse de utilizator, cum ar fi:

cuvânt aleator £500 de bancă $

Vreau ca rezultatul sa fie corect codificate URL:

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

Ce's cel mai bun mod de a realiza acest lucru? Am încercat URLEncoder și crearea URI/URL obiecte, dar nici unul dintre ei iese destul de bine.

Comentarii la întrebare (4)
Soluția

URLEncoder ar trebui să fie calea de a merge. Ai nevoie doar pentru a păstra în minte pentru a codifica numai individuale șir de interogare parametru numele și/sau valoare, nu întregul URL-ul, pentru că nu șirul de interogare parametru caracter separator &, nici nume parametru-valoare separator caracterul =.

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

Rețineți că spațiile în parametrii de interogare sunt reprezentate de +, nu %20, care este legal valabil. A %20 este, de obicei, pentru a fi utilizate pentru a reprezenta spații URI în sine (partea dinainte URI-șir de interogare separator caracterul ?), nu în șirul de interogare (partea de după ?).

De asemenea, rețineți că există două encode() metode. Una fără de caractere argument și un alt cu. Cel fără de caractere argument este învechită. Nu utilizați niciodată și întotdeauna specifica setul de caractere argument. De javadoc chiar și în mod explicit recomandă să utilizați codificarea UTF-8, în calitate de împuternicit RFC3986 și W3C.

Toate celelalte caractere sunt nesigure și sunt mai întâi transformat într-unul sau mai mulți octeți, folosind un sistem de codificare. Apoi, fiecare octet este reprezentat de 3-șir de caractere "%xy", unde xy este de două cifre hexazecimale reprezentarea octet. Recomandate schema de codare pentru a utiliza este UTF-8. Cu toate acestea, din motive de compatibilitate, dacă o codificare nu este specificat, atunci codarea implicită a platformei este folosit.

Se vedea, de asemenea:

  • [Ce fiecare dezvoltator web trebuie să știți despre codare URL][5]

[5]: https://www.talisman.org/~erlkonig/misc/lunatech%5Ewhat-fiecare-webdev-trebuie să-stii-despre-url-urile de codificare/

Comentarii (11)

Nu aș folosi URLEncoder. În afară de a fi incorect numit (URLEncoder nu are nimic de-a face cu Url-uri), ineficiente (se folosește un StringBuffer` în loc de Constructor și un cuplu de alte lucruri care sunt lent) Sale, de asemenea, mult prea ușor să dai în bară.

În schimb mi-ar folosi URIBuilder sau Izvor's org.springframework.web.util.UriUtils.encodeQuery sau Apache Commons HttpClient. Motivul fiind că trebuie să scape de parametrii de interogare nume (ie BalusC's a răspunde "q") altfel decât valoarea parametrului.

Singurul dezavantaj la cele de mai sus (de care am aflat dureros) este că URL's nu sunt un adevărat subset de URI's.

Mostre de cod:

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

De când am'm doar conectarea la alte răspunsuri am marcat acest lucru ca pe o comunitate wiki. Simțiți-vă liber pentru a edita.

Comentarii (9)

Aveți nevoie să creați mai întâi un URI, cum ar fi:

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

Apoi converti Uri ASCII string:

    urlStr=uri.toASCIIString();

Acum url string este complet codificat în primul rând am făcut-o simplă codificare url-ul și apoi ne-am convertit în Șir ASCII pentru a asigurați-vă că nici un personaj din afara US-ASCII sunt rămase în șir. Acest lucru este exact modul în care browserele.

Comentarii (10)

Apache Http Componente de bibliotecă oferă un elegant opțiune pentru construirea și codare interogare params -

Cu HttpComponents 4.x utilizați - URLEncodedUtils

Pentru HttpClient 3.x utilizați - EncodingUtil

Comentarii (0)

Aici's o metodă puteți folosi în cod pentru a converti un șir url și harta de parametri de la un valabile codificat url string care conține parametrii de interogare.

String addQueryStringToUrlString(String url, final Map parameters) throws UnsupportedEncodingException {
    if (parameters == null) {
        return url;
    }

    for (Map.Entry 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;
}
Comentarii (0)

Utilizați următoarele Java standard soluție (trece în jurul valorii de 100 de testcases furnizate de Web Plattform Teste):

0. Test dacă URL-ul este deja codificat. Înlocuiți '+' codificate spații cu '%20' codat spații.

1. Split URL-ul în părți structurale. Folosesc java.net.URL-ul pentru asta.

2. Codifica fiecare parte structurală în mod corespunzător!

3. Utilizarea IDN.toASCII(putDomainNameHere) a Punycode codifica numele de gazdă!

4. Folosesc java.net.URI.toASCIIString()` a la sută-encode, NFC codificate unicode (mai bine ar fi NFKC!). Pentru mai multe informații a se vedea: https://stackoverflow.com/questions/49768599/how-to-encode-properly-this-url/49778055#49778055

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

Printuri

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

Aici sunt câteva exemple care va lucra, de asemenea, în mod corespunzător

{
      "in" : "http://نامه‌ای.com/",
     "out" : "http://xn--mgba3gch31f.com/"
},{
     "in" : "http://www.example.com/‥/foo",
     "out" : "http://www.example.com/%E2%80%A5/foo"
},{
     "in" : "http://search.barnesandnoble.com/booksearch/first book.pdf", 
     "out" : "http://search.barnesandnoble.com/booksearch/first%20book.pdf"
}, {
     "in" : "http://example.com/query?q=random word £500 bank $", 
     "out" : "http://example.com/query?q=random%20word%20%C2%A3500%20bank%20$"
}
Comentarii (0)

În cazul meu, am nevoie doar pentru a trece tot url-ul și codifica numai valoarea fiecărui parametru. Am't găsi un cod comun pentru a face asta atât de (!!) așa că am creat acest mic metodă de a face treaba :

public static String encodeUrl(String url) throws Exception {
    if (url == null || !url.contains("?")) {
        return url;
    }

    List list = new ArrayList();
    String rootUrl = url.split("\\?")[0] + "?";
    String paramsUrl = url.replace(rootUrl, "");
    List paramsUrlList = Arrays.asList(paramsUrl.split("&"));
    for (String param : paramsUrlList) {
        if (param.contains("=")) {
            String key = param.split("=")[0];
            String value = param.replace(key + "=", "");
            list.add(key + "=" +  URLEncoder.encode(value, "UTF-8"));
        }
        else {
            list.add(param);
        }
    }

    return rootUrl + StringUtils.join(list, "&");
}

public static String decodeUrl(String url) throws Exception {
    return URLDecoder.decode(url, "UTF-8");
}

Folosește org.apache.commons.lang3.StringUtils

Comentarii (0)

În android mi-ar folosi acest cod:

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

Unde Uri e un android.net.Uri

Comentarii (1)
  1. Utilizați această: URLEncoder.codifica(interogare, StandardCharsets.UTF_8.displayName()); sau asta:URLEncoder.codifica(interogare, "UTF-8");
  2. Puteți utiliza urmatoarele cod.

String encodedUrl1 = UriUtils.encodeQuery(interogare, "UTF-8");//nu se modifica String encodedUrl2 = URLEncoder.codifica(interogare, "UTF-8");//s-a schimbat String encodedUrl3 = URLEncoder.codifica(interogare, StandardCharsets.UTF_8.displayName());//s-a schimbat

Sistem.afară.println("url1 " + encodedUrl1 + "\n" + "url2=" + encodedUrl2 + "\n" + "url3=" + encodedUrl3);

Comentarii (1)