Кодирование Java URL параметров строки запроса
скажем, у меня есть URL
http://example.com/query?q=
и у меня есть запрос, введенный пользователем, такие как:
случайное слово £500 bank $
Я хочу, чтобы результат был правильно закодированным URL:
http://example.com/query?q=random%20word%20%A3500%20bank%20%24
каков наилучший способ достичь этого? Я пытался!--2--> и создание объектов URI/URL, но ни один из них не выходит совершенно правильно.
9 ответов
URLEncoder
должен быть путь пойти. Нужно только иметь в виду, чтобы кодировать только имя и/или значение отдельного параметра строки запроса, а не весь URL-адрес, точно не символ разделителя параметров строки запроса &
ни имя параметра-символ разделителя значений =
.
String q = "random word £500 bank $";
String url = "http://example.com/query?q=" + URLEncoder.encode(q, "UTF-8");
обратите внимание, что пробелы в параметрах запроса представлены +
, а не %20
, что является законным. The %20
is обычно используется для представления пробелов в самом URI (часть перед символом разделителя строки URI-запроса ?
), а не в строке запроса (после ?
).
также обратите внимание, что есть два encode()
методы. Один без аргумента charset, а другой с. Без charset параметр является устаревшим. Никогда не используйте его и всегда указывайте аргумент charset. The javadoc даже прямо рекомендует использовать кодировку UTF-8, как это предусмотрено RFC3986 и W3C по.
все остальные символы небезопасны и сначала преобразуются в один или несколько байтов, используя некоторую схему кодирования. Затем каждый байт представлен 3-символьной строкой "%xy", где xy-двузначное шестнадцатеричное представление байта. рекомендуемая схема кодирования для использования-UTF-8. Однако, по соображениям совместимости, если кодировка не указана, то кодировка по умолчанию платформы предназначенный.
Читайте также:
Я бы не использовать URLEncoder
. Кроме того, неправильно назван (URLEncoder
Не имеет ничего общего с URL-адресами), неэффективно (он использует StringBuffer
вместо Builder и делает пару других вещей, которые медленные) его также слишком легко испортить.
вместо этого я бы использовал 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 не остается в строке. Именно так поступают браузеры.
Apache Http Components library предоставляет аккуратный вариант для построения и кодирования запросов params -
С 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)
to в 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
- используйте это: URLEncoder.encode (query, StandardCharsets.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);