Кодирование 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, но ни один из них не выходит совершенно правильно.
9 ответов:
URLEncoderдолжен быть путь пойти. Нужно только иметь в виду, чтобы кодировать только имя и/или значение отдельного параметра строки запроса, а не весь URL-адрес, конечно, не символ разделителя параметров строки запроса&и символ разделителя имя-значение параметра=.String q = "random word £500 bank $"; String url = "http://example.com/query?q=" + URLEncoder.encode(q, "UTF-8");
обратите внимание, что пробелы в параметрах запроса представлены
+, а не%20, что является законно действительным. Элемент%20is обычно используется для представления пробелов в самом 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 ApacheHttpClient. Причина в том, что вам нужно избежать имени параметров запроса (т. е. ответа BalusCq) иначе, чем значение параметра.единственным недостатком выше (что я узнал болезненно) является то, что 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!). Для получения дополнительной информации см.:Как правильно закодировать этот URLURL 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
- используйте это: URLEncoder.кодирование(запрос, стандартные наборы символов.UTF_8.значение DisplayName()); или вот это: URLEncoder.encode (query, "UTF-8");
вы можете использовать код ниже.
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