Кодирование Java URL параметров строки запроса



скажем, у меня есть URL



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


и у меня есть запрос, введенный пользователем, такие как:




случайное слово £500 bank $




Я хочу, чтобы результат был правильно закодирован URL:



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


каков наилучший способ достичь этого? Я пытался URLEncoder и создание объектов URI / URL, но ни один из них не выходит совершенно правильно.

967   9  

9 ответов:

URLEncoder должен быть путь пойти. Нужно только иметь в виду, чтобы кодировать только имя и/или значение отдельного параметра строки запроса, а не весь URL-адрес, конечно, не символ разделителя параметров строки запроса & и символ разделителя имя-значение параметра =.

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

обратите внимание, что пробелы в параметрах запроса представлены +, а не %20, что является законно действительным. Элемент %20 is обычно используется для представления пробелов в самом URI (часть перед символом разделителя строки URI-запроса ?), а не в строке запроса (после ?).

также обратите внимание, что есть два encode() методы. Один без аргумента charset, а другой с. Без charset параметр является устаревшим. Никогда не используйте его и всегда указывайте аргумент charset. Элемент документация даже явно рекомендует использовать кодировку UTF-8, как предписано RFC3986 и W3C.

все остальные символы небезопасны и сначала преобразуются в один или несколько байтов с помощью некоторой схемы кодирования. Затем каждый байт представляется 3-символьной строкой "%xy", где xy-двузначное шестнадцатеричное представление байта. рекомендуется использовать схему кодирования UTF-8. Однако, по соображениям совместимости, если кодировка не указана, то кодировка по умолчанию платформы предназначенный.

Читайте также:

Я бы не использовать URLEncoder. Кроме того, неправильно назван (URLEncoder Не имеет ничего общего с URL-адресами), неэффективно (он использует StringBuffer вместо строителя и пару других вещей, которые медленно) его слишком легко испортить.

вместо этого я бы использовал URIBuilder или весной org.springframework.web.util.UriUtils.encodeQuery или Commons Apache HttpClient. Причина в том, что вам нужно избежать имени параметров запроса (т. е. ответа BalusC q) иначе, чем значение параметра.

единственным недостатком выше (что я узнал болезненно) является то, что URL-адреса не являются истинным подмножеством URI.

пример кода:

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

поскольку я просто ссылаюсь на другие ответы, я отметил это как Вики-сообщество. Не стесняйтесь редактировать.

вы должны сначала создать URI, как:

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

затем преобразуйте этот Uri в строку ASCII:

    urlStr=uri.toASCIIString();

теперь ваша строка url полностью закодирована сначала мы сделали простую кодировку url, а затем мы преобразовали ее в строку ASCII, чтобы убедиться, что никакой символ вне нас-ASCII не остается в строке. Именно так и делают браузеры.

Guava 15 теперь добавил набор простых эскейперов URL.

библиотека Http-компонентов Apache предоставляет аккуратный вариант для построения и кодирования параметров запроса -

С HttpComponents 4.X использование - URLEncodedUtils

Для HttpClient 3.X использование - EncodingUtil

вот метод, который вы можете использовать в своем коде для преобразования строки url и сопоставления параметров в допустимую закодированную строку url, содержащую параметры запроса.

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

1. разделить URL на структурные части. Используйте java.net.URL для него.

2. кодировать каждую структурную часть правильно!

3. использовать IDN.toASCII(putDomainNameHere) до Punycode кодировать имя хоста!

4. использовать java.net.URI.toASCIIString() для процентного кодирования, NFC кодируется unicode- (лучше бы NFKC!). Для получения дополнительной информации см.:Как правильно закодировать этот 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);

печать

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

В android я бы использовал этот код:

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

здесь Uri это android.net.Uri

  1. используйте это: URLEncoder.кодирование(запрос, стандартные наборы символов.UTF_8.значение DisplayName()); или вот это: URLEncoder.encode (query, "UTF-8");
  2. вы можете использовать код ниже.

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

Comments

    Ничего не найдено.